105 lines
3.7 KiB
Python
105 lines
3.7 KiB
Python
#! /usr/bin/env python
|
|
# -*- coding: utf-8 -*-
|
|
|
|
"""Automatic Docker Deployment via Webhooks."""
|
|
|
|
import json
|
|
import os
|
|
from subprocess import Popen
|
|
from argparse import ArgumentParser, ArgumentDefaultsHelpFormatter
|
|
from http.server import HTTPServer
|
|
from http.server import BaseHTTPRequestHandler
|
|
import sys
|
|
import logging
|
|
import requests
|
|
|
|
logging.basicConfig(format='%(asctime)s %(levelname)s %(message)s',
|
|
level=logging.DEBUG,
|
|
stream=sys.stdout)
|
|
|
|
class RequestHandler(BaseHTTPRequestHandler):
|
|
"""A POST request handler which expects a token in its path."""
|
|
|
|
def do_POST(self):
|
|
try:
|
|
logging.info("Path: %s", self.path)
|
|
header_length = int(self.headers.get('content-length', "0"))
|
|
json_payload = self.rfile.read(header_length)
|
|
env = dict(os.environ)
|
|
json_params = {}
|
|
if len(json_payload) > 0:
|
|
json_params = json.loads(json_payload)
|
|
env.update(('REPOSITORY_' + var.upper(), str(val))
|
|
for var, val in json_params['repository'].items())
|
|
|
|
logging.info("Start executing '%s'" % args.cmd)
|
|
try:
|
|
Popen(args.cmd, env=env).wait()
|
|
self.send_response(200, "OK")
|
|
if 'callback_url' in json_params:
|
|
# Make a callback to Docker Hub
|
|
data = {'state': 'success'}
|
|
headers = {'Content-type': 'application/json',
|
|
'Accept': 'text/plain'}
|
|
requests.post(json_params['callback_url'],
|
|
data=json.dumps(data),
|
|
headers=headers)
|
|
except OSError as err:
|
|
self.send_response(500, "OSError")
|
|
logging.error("You probably didn't use 'sh ./script.sh'.")
|
|
logging.error(err)
|
|
if 'callback_url' in json_params:
|
|
# Make a callback to Docker Hub
|
|
data = {'state': 'failure',
|
|
'description': str(err)}
|
|
headers = {'Content-type': 'application/json',
|
|
'Accept': 'text/plain'}
|
|
requests.post(json_params['callback_url'],
|
|
data=json.dumps(data),
|
|
headers=headers)
|
|
self.end_headers()
|
|
except Exception as e:
|
|
logging.error(e)
|
|
|
|
|
|
def get_parser():
|
|
"""Get a command line parser for docker-hook."""
|
|
parser = ArgumentParser(description=__doc__,
|
|
formatter_class=ArgumentDefaultsHelpFormatter)
|
|
|
|
parser.add_argument("-t", "--token",
|
|
dest="token",
|
|
required=False,
|
|
help=("Secure auth token (can be choosen "
|
|
"arbitrarily)"))
|
|
parser.add_argument("-c", "--cmd",
|
|
dest="cmd",
|
|
required=True,
|
|
nargs="*",
|
|
help="Command to execute when triggered")
|
|
parser.add_argument("--addr",
|
|
dest="addr",
|
|
default="0.0.0.0",
|
|
help="address where it listens")
|
|
parser.add_argument("--port",
|
|
dest="port",
|
|
type=int,
|
|
default=8555,
|
|
metavar="PORT",
|
|
help="port where it listens")
|
|
return parser
|
|
|
|
|
|
def main(addr, port):
|
|
"""Start a HTTPServer which waits for requests."""
|
|
httpd = HTTPServer((addr, port), RequestHandler)
|
|
httpd.serve_forever()
|
|
|
|
if __name__ == '__main__':
|
|
parser = get_parser()
|
|
if len(sys.argv) == 1:
|
|
parser.print_help()
|
|
sys.exit(1)
|
|
args = parser.parse_args()
|
|
main(args.addr, args.port)
|