This commit is contained in:
japrogramer 2017-08-10 12:13:20 +00:00 committed by GitHub
commit ca0a7b4194
5 changed files with 118 additions and 48 deletions

View File

@ -10,11 +10,11 @@ COPY ./requirements /requirements
RUN pip install --no-cache-dir -r /requirements/production.txt \
&& rm -rf /requirements
COPY ./compose/django/gunicorn.sh ./compose/django/entrypoint.sh /
RUN sed -i 's/\r//' /entrypoint.sh \
COPY ./compose/django/gunicorn.sh ./compose/django/entrypoint.py /
RUN sed -i 's/\r//' /entrypoint.py \
&& sed -i 's/\r//' /gunicorn.sh \
&& chmod +x /entrypoint.sh \
&& chown django /entrypoint.sh \
&& chmod +x /entrypoint.py \
&& chown django /entrypoint.py \
&& chmod +x /gunicorn.sh \
&& chown django /gunicorn.sh
@ -26,4 +26,4 @@ USER django
WORKDIR /app
ENTRYPOINT ["/entrypoint.sh"]
ENTRYPOINT ["/entrypoint.py"]

View File

@ -5,9 +5,9 @@ ENV PYTHONUNBUFFERED 1
COPY ./requirements /requirements
RUN pip install -r /requirements/local.txt
COPY ./compose/django/entrypoint.sh /entrypoint.sh
RUN sed -i 's/\r//' /entrypoint.sh
RUN chmod +x /entrypoint.sh
COPY ./compose/django/entrypoint.py /entrypoint.py
RUN sed -i 's/\r//' /entrypoint.py
RUN chmod +x /entrypoint.py
COPY ./compose/django/start-dev.sh /start-dev.sh
RUN sed -i 's/\r//' /start-dev.sh
@ -15,4 +15,4 @@ RUN chmod +x /start-dev.sh
WORKDIR /app
ENTRYPOINT ["/entrypoint.sh"]
ENTRYPOINT ["/entrypoint.py"]

View File

@ -0,0 +1,75 @@
#!/usr/bin/env python
"""
# This entrypoint is used to play nicely with the current cookiecutter configuration.
# Since docker-compose relies heavily on environment variables itself for configuration, we'd have to define multiple
# environment variables just to support cookiecutter out of the box. That makes no sense, so this little entrypoint
# does all this for us.
"""
from __future__ import print_function
import os
import sys
import psycopg2
import time
def exports(**kwargs):
"""Useful environment variables
:list: TODO
"""
os.environ['REDIS_URL'] = 'redis://redis:6379'
os.environ['CELERY_BROKER_URL'] = os.environ['REDIS_URL'] + '/0'
def pingpost():
"""
This is the function that actually trys to connect
to postgres
"""
try:
if os.environ['POSTGRES_USER']:
pg_user = os.environ['POSTGRES_USER']
else:
os.environ['POSTGRES_USER'] = pg_user = 'postgres'
try:
pg_pass = os.environ['POSTGRES_PASSWORD']
except Exception as e:
pg_pass = ''
DATABASE_URL='postgres://{username}:{password}@postgres:5432/{username}'
DATABASE_URL = DATABASE_URL.format(username=pg_user, password=pg_pass)
os.environ['DATABASE_URL'] = DATABASE_URL
conn = psycopg2.connect(DATABASE_URL, connect_timeout=3)
except psycopg2.OperationalError as error:
print(error)
return False
return True
def main(arguments):
"""
call exports
and check to see if postgres is ready
"""
exports()
while True:
if pingpost():
break
print('Postgres is unavailable - sleeping')
time.sleep(1)
import subprocess
try:
hold = subprocess.check_call(arguments)
except subprocess.CalledProcessError as cpe:
print("something went wrong")
raise Exception(cpe)
print('exiting: ...')
if __name__ == '__main__':
sys.exit(main(sys.argv[1:]))

View File

@ -1,39 +0,0 @@
#!/bin/bash
set -e
cmd="$@"
# This entrypoint is used to play nicely with the current cookiecutter configuration.
# Since docker-compose relies heavily on environment variables itself for configuration, we'd have to define multiple
# environment variables just to support cookiecutter out of the box. That makes no sense, so this little entrypoint
# does all this for us.
export REDIS_URL=redis://redis:6379
# the official postgres image uses 'postgres' as default user if not set explictly.
if [ -z "$POSTGRES_USER" ]; then
export POSTGRES_USER=postgres
fi
export DATABASE_URL=postgres://$POSTGRES_USER:$POSTGRES_PASSWORD@postgres:5432/$POSTGRES_USER
{% if cookiecutter.use_celery == 'y' %}
export CELERY_BROKER_URL=$REDIS_URL/0
{% endif %}
function postgres_ready(){
python << END
import sys
import psycopg2
try:
conn = psycopg2.connect(dbname="$POSTGRES_USER", user="$POSTGRES_USER", password="$POSTGRES_PASSWORD", host="postgres")
except psycopg2.OperationalError:
sys.exit(-1)
sys.exit(0)
END
}
until postgres_ready; do
>&2 echo "Postgres is unavailable - sleeping"
sleep 1
done
>&2 echo "Postgres is up - continuing..."
exec $cmd

View File

@ -0,0 +1,34 @@
from unittest.mock import patch, PropertyMock
import unittest
import entrypoint
class TestEntrypoint(unittest.TestCase):
"""
We test that the entry point script works.
"""
def setUp(self):
self.prop = 'test'
def test_exports(self):
with patch.dict(entrypoint.os.environ, {'newkey': 'newvalue'}, clear=True):
entrypoint.exports()
self.assertTrue(entrypoint.os.environ['REDIS_URL'])
self.assertTrue(entrypoint.os.environ['CELERY_BROKER_URL'])
self.assertTrue(entrypoint.os.environ['newkey'])
@patch('entrypoint.psycopg2.connect')
def test_pingpost(self, mockConn):
"""
We must assert that psycopg2 conn is called
"""
with patch.dict(entrypoint.os.environ, {
'POSTGRES_USER': 'newvalue',
'POSTGRES_PASSWORD': 'test'}, clear=True):
entrypoint.main(('dir',))
self.assertTrue(entrypoint.os.environ['DATABASE_URL'])
self.assertTrue(mockConn.called)
if __name__ == '__main__':
unittest.main()