diff --git a/Dockerfile b/Dockerfile index faaa21f6..53d56965 100644 --- a/Dockerfile +++ b/Dockerfile @@ -11,7 +11,7 @@ RUN apt-get update -y RUN apt-get upgrade -y ENV PGVERSION 9.4 -RUN apt-get install curl python python-pip python-psycopg2 python-yaml python-cherrypy postgresql-${PGVERSION} -y +RUN apt-get install curl python python-pip python-psycopg2 python-yaml postgresql-${PGVERSION} -y RUN ln -s /usr/lib/postgresql/* /usr/lib/postgresql/current ENV PATH /usr/lib/postgresql/current/bin:$PATH diff --git a/governor.py b/governor.py index 7492b0e5..680bbb71 100755 --- a/governor.py +++ b/governor.py @@ -2,10 +2,12 @@ import sys, os, yaml, time, urllib2, atexit import logging +import threading from helpers.etcd import Etcd from helpers.postgresql import Postgresql from helpers.ha import Ha +from helpers.statuspage import StatusPage, getHTTPServer INSTANCE_METADATA_URL = "http://169.254.169.254/latest/meta-data/" @@ -30,6 +32,12 @@ etcd = Etcd(config["etcd"]) postgresql = Postgresql(config["postgresql"], aws_host_address) ha = Ha(postgresql, etcd) +## Start the http_server to serve a simple healthcheck +http_server = getHTTPServer(postgresql, http_port=8080, listen_address='0.0.0.0') +http_thread = threading.Thread(target=http_server.serve_forever, args=()) +http_thread.daemon = True +http_thread.start() + # stop postgresql on script exit def stop_postgresql(): postgresql.stop() diff --git a/helpers/statuspage.py b/helpers/statuspage.py new file mode 100644 index 00000000..67fdb4ab --- /dev/null +++ b/helpers/statuspage.py @@ -0,0 +1,58 @@ +#!/usr/bin/env python +# -*- coding: utf-8 -*- + +from BaseHTTPServer import BaseHTTPRequestHandler, HTTPServer + + +class StatusPage(BaseHTTPRequestHandler): + + def do_GET(self): + try: + if self.path == '/pg_master': + response = (200 if self.server.postgresql.is_leader else 503) + self.send_response(response) + elif self.path == '/pg_slave': + response = (503 if self.server.postgresql.is_leader else 200) + self.send_response(response) + elif self.path == '/pg_status': + self.send_response(200) + self.end_headers() + self.wfile.write(self.server.postgresql.status()) + else: + self.send_response(404) + except Exception, e: + self.send_response(500) + self.end_headers() + self.wfile.write(repr(e)) + + +def getHTTPServer(postgresql, http_port=8081, listen_address='0.0.0.0'): + server = HTTPServer((listen_address, http_port), StatusPage) + server.postgresql = postgresql + + return server + + +if __name__ == '__main__': + import sys + import logging + from BaseHTTPServer import HTTPServer + + logging.basicConfig(format='%(levelname)-6s %(asctime)s - %(message)s', level=logging.DEBUG) + logging.debug('Starting as a standalone application') + + # # Create a dummy configuration to be able to use the Postgresql class + from postgresql import Postgresql + postgres_config = { + 'name': 'dummy', + 'listen': 'localhost:5432', + 'data_dir': None, + 'replication': {'username': None, 'password': None}, + } + aws_host_address = None + if len(sys.argv) > 1: + postgres_config['listen'] = sys.argv[1] + postgresql = Postgresql(postgres_config, aws_host_address) + + getHTTPServer(postgresql, 8081, '0.0.0.0').serve_forever() + logging.debug('Abc') diff --git a/requirements.txt b/requirements.txt new file mode 100644 index 00000000..377437fe --- /dev/null +++ b/requirements.txt @@ -0,0 +1,2 @@ +PyYAML +psycopg2