From 1e9bc49f2cbd6f4cd077701e279b30445b4370ff Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Andr=C3=A9?= Date: Fri, 27 Oct 2017 11:22:39 +0200 Subject: [PATCH] [Rspamd] Echo dummy for fowardingshosts map; Use higher map reading interval; [Dockerapi] Exit on sigterm; [Watchdog] Wait for dockerapi-mailcow to be online --- data/Dockerfiles/dockerapi/server.py | 105 +++++++++++-------- data/Dockerfiles/watchdog/watchdog.sh | 16 +++ data/conf/rspamd/dynmaps/forwardinghosts.php | 4 +- data/conf/rspamd/local.d/options.inc | 2 +- docker-compose.yml | 6 +- 5 files changed, 88 insertions(+), 45 deletions(-) diff --git a/data/Dockerfiles/dockerapi/server.py b/data/Dockerfiles/dockerapi/server.py index a021ab54..aabcaf31 100644 --- a/data/Dockerfiles/dockerapi/server.py +++ b/data/Dockerfiles/dockerapi/server.py @@ -1,62 +1,85 @@ from flask import Flask from flask_restful import Resource, Api from flask import jsonify +from threading import Thread import docker +import signal +import time docker_client = docker.DockerClient(base_url='unix://var/run/docker.sock') app = Flask(__name__) api = Api(app) class containers_get(Resource): - def get(self): - containers = {} - for container in docker_client.containers.list(all=True): - containers.update({container.attrs['Id']: container.attrs}) - return containers + def get(self): + containers = {} + for container in docker_client.containers.list(all=True): + containers.update({container.attrs['Id']: container.attrs}) + return containers class container_get(Resource): - def get(self, container_id): - if container_id and container_id.isalnum(): - for container in docker_client.containers.list(all=True, filters={"id": container_id}): - return container.attrs - else: - return jsonify(message='No or invalid id defined') + def get(self, container_id): + if container_id and container_id.isalnum(): + for container in docker_client.containers.list(all=True, filters={"id": container_id}): + return container.attrs + else: + return jsonify(message='No or invalid id defined') class container_post(Resource): - def post(self, container_id, post_action): - if container_id and container_id.isalnum() and post_action: - if post_action == 'stop': - try: - for container in docker_client.containers.list(all=True, filters={"id": container_id}): - container.stop() - except: - return 'Error' - else: - return 'OK' - elif post_action == 'start': - try: - for container in docker_client.containers.list(all=True, filters={"id": container_id}): - container.start() - except: - return 'Error' - else: - return 'OK' - elif post_action == 'restart': - try: - for container in docker_client.containers.list(all=True, filters={"id": container_id}): - container.restart() - except: - return 'Error' - else: - return 'OK' - else: - return jsonify(message='Invalid action') + def post(self, container_id, post_action): + if container_id and container_id.isalnum() and post_action: + if post_action == 'stop': + try: + for container in docker_client.containers.list(all=True, filters={"id": container_id}): + container.stop() + except: + return 'Error' else: - return jsonify(message='Invalid container id or missing action') + return 'OK' + elif post_action == 'start': + try: + for container in docker_client.containers.list(all=True, filters={"id": container_id}): + container.start() + except: + return 'Error' + else: + return 'OK' + elif post_action == 'restart': + try: + for container in docker_client.containers.list(all=True, filters={"id": container_id}): + container.restart() + except: + return 'Error' + else: + return 'OK' + else: + return jsonify(message='Invalid action') + else: + return jsonify(message='Invalid container id or missing action') + +class GracefulKiller: + kill_now = False + def __init__(self): + signal.signal(signal.SIGINT, self.exit_gracefully) + signal.signal(signal.SIGTERM, self.exit_gracefully) + + def exit_gracefully(self,signum, frame): + self.kill_now = True + +def startFlaskAPI(): + app.run(debug=False, host='0.0.0.0', port='8080', threaded=True) api.add_resource(containers_get, '/containers/json') api.add_resource(container_get, '/containers//json') api.add_resource(container_post, '/containers//') if __name__ == '__main__': - app.run(debug=False, host='0.0.0.0', port='8080') + api_thread = Thread(target=startFlaskAPI) + api_thread.daemon = True + api_thread.start() + killer = GracefulKiller() + while True: + time.sleep(1) + if killer.kill_now: + break + print "Stopping dockerapi-mailcow" diff --git a/data/Dockerfiles/watchdog/watchdog.sh b/data/Dockerfiles/watchdog/watchdog.sh index 470025de..d7351936 100755 --- a/data/Dockerfiles/watchdog/watchdog.sh +++ b/data/Dockerfiles/watchdog/watchdog.sh @@ -360,6 +360,22 @@ while true; do done ) & +# Monitor dockerapi +( +while true; do + while nc -z dockerapi 8080; do + sleep 3 + done + echo "Cannot find dockerapi-mailcow, waiting to recover..." + kill -STOP ${BACKGROUND_TASKS[*]} + until nc -z dockerapi 8080; do + sleep 3 + done + kill -CONT ${BACKGROUND_TASKS[*]} + kill -USR1 ${BACKGROUND_TASKS[*]} +done +) & + # Restart container when threshold limit reached while true; do CONTAINER_ID= diff --git a/data/conf/rspamd/dynmaps/forwardinghosts.php b/data/conf/rspamd/dynmaps/forwardinghosts.php index 522a21f9..10285b71 100644 --- a/data/conf/rspamd/dynmaps/forwardinghosts.php +++ b/data/conf/rspamd/dynmaps/forwardinghosts.php @@ -44,11 +44,13 @@ if (isset($_GET['host'])) { } } else { try { + echo '240.240.240.240' . PHP_EOL; foreach ($redis->hGetAll('WHITELISTED_FWD_HOST') as $host => $source) { - echo $host . "\n"; + echo $host . PHP_EOL; } } catch (RedisException $e) { + echo '240.240.240.240' . PHP_EOL; exit; } } diff --git a/data/conf/rspamd/local.d/options.inc b/data/conf/rspamd/local.d/options.inc index bb940b3f..09117984 100644 --- a/data/conf/rspamd/local.d/options.inc +++ b/data/conf/rspamd/local.d/options.inc @@ -1,7 +1,7 @@ dns { enable_dnssec = true; } -map_watch_interval = 15s; +map_watch_interval = 60s; dns { timeout = 4s; retransmits = 5; diff --git a/docker-compose.yml b/docker-compose.yml index 56f8459c..ae908b1f 100644 --- a/docker-compose.yml +++ b/docker-compose.yml @@ -215,12 +215,14 @@ services: depends_on: - sogo-mailcow - php-fpm-mailcow + - redis-mailcow image: nginx:mainline-alpine command: /bin/sh -c "envsubst < /etc/nginx/conf.d/templates/listen_plain.template > /etc/nginx/conf.d/listen_plain.active && envsubst < /etc/nginx/conf.d/templates/listen_ssl.template > /etc/nginx/conf.d/listen_ssl.active && envsubst < /etc/nginx/conf.d/templates/server_name.template > /etc/nginx/conf.d/server_name.active && nginx -qt && until ping phpfpm -c1 > /dev/null; do sleep 1; done && + until ping redis -c1 > /dev/null; do sleep 1; done && exec nginx -g 'daemon off;'" environment: - HTTPS_PORT=${HTTPS_PORT:-443} @@ -291,7 +293,7 @@ services: - /lib/modules:/lib/modules:ro watchdog-mailcow: - image: mailcow/watchdog:1.8 + image: mailcow/watchdog:1.9 build: ./data/Dockerfiles/watchdog volumes: - vmail-vol-1:/vmail:ro @@ -310,7 +312,7 @@ services: - watchdog dockerapi-mailcow: - image: mailcow/dockerapi:1.0 + image: mailcow/dockerapi:1.1 stop_grace_period: 3s build: ./data/Dockerfiles/dockerapi volumes: