From 900ec8b9110225eb807d214a6e52897b7a29b585 Mon Sep 17 00:00:00 2001 From: Yohann D'ANELLO Date: Wed, 10 Jun 2020 16:50:00 +0200 Subject: [PATCH] :heavy_plus_sign: The server works :) --- Dockerfile | 27 +++++++++++++ docker-hook | 104 ++++++++++++++++++++++++++++++++++++++++++++++++++ entrypoint.sh | 9 +++++ nginx.conf | 17 +++++++++ update.sh | 4 ++ 5 files changed, 161 insertions(+) create mode 100644 Dockerfile create mode 100644 docker-hook create mode 100755 entrypoint.sh create mode 100644 nginx.conf create mode 100755 update.sh diff --git a/Dockerfile b/Dockerfile new file mode 100644 index 0000000..3b7661c --- /dev/null +++ b/Dockerfile @@ -0,0 +1,27 @@ +FROM python:3-alpine + +RUN apk --update add git less openssh nginx curl gcc libc-dev && \ + rm -rf /var/lib/apt/lists/* && \ + rm /var/cache/apk/* + +RUN pip install requests --no-cache-dir + +RUN mkdir /hook && mkdir /docs && mkdir /site + +# Configure nginx +RUN mkdir /run/nginx +RUN ln -sf /dev/stdout /var/log/nginx/access.log && ln -sf /dev/stderr /var/log/nginx/error.log +COPY nginx.conf /etc/nginx/conf.d/organiser-un-tfjm.conf +RUN rm /etc/nginx/conf.d/default.conf + +COPY ./entrypoint.sh /hook +COPY ./docker-hook /hook +COPY ./update.sh /hook + +WORKDIR /docs + +RUN umask 0002 + +ENTRYPOINT ["/hook/entrypoint.sh"] + +EXPOSE 80 diff --git a/docker-hook b/docker-hook new file mode 100644 index 0000000..aa472a2 --- /dev/null +++ b/docker-hook @@ -0,0 +1,104 @@ +#! /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) diff --git a/entrypoint.sh b/entrypoint.sh new file mode 100755 index 0000000..577189d --- /dev/null +++ b/entrypoint.sh @@ -0,0 +1,9 @@ +#!/bin/sh + +[ -d .git ] || git clone ${MKDOCS_SERVER_GIT_URL} /docs + +git pull +pip install -r requirements.txt +mkdocs build -d /site +nginx& +python /hook/docker-hook -c sh /hook/update.sh diff --git a/nginx.conf b/nginx.conf new file mode 100644 index 0000000..62304eb --- /dev/null +++ b/nginx.conf @@ -0,0 +1,17 @@ +upstream trigger-ci { + server 127.0.0.1:8555; +} + +server { + listen 80; + server_name organisation; + root /site; + error_page 404 /404.html; + + location /trigger-ci.json { + proxy_pass http://trigger-ci; + proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for; + proxy_set_header Host $host; + proxy_redirect off; + } +} diff --git a/update.sh b/update.sh new file mode 100755 index 0000000..1c73ad9 --- /dev/null +++ b/update.sh @@ -0,0 +1,4 @@ +#!/bin/sh + +git pull +mkdocs build -d /site