Eine Vorlage für Ihre eigene Flasche.
Die API für Hook of Bitbucket und Github ist ein API-Server (gunicorn, der nach dem Ziehen in Upstart registriert ist. )) Wird neu gestartet.
Ich habe GitPython für die Arbeit mit dem Git-Repository hinzugefügt.
Pfeil ist ebenfalls in der Verarbeitung enthalten.
server.py
# -*- coding: utf-8 -*-
import commands
import os.path
import traceback
from decorator import decorator
import logging
import subprocess
import getpass
from bottle import get, post, put, delete, run, default_app, request, response, HTTPError, redirect, local, abort
from bottle import static_file, route
import arrow
from git import Repo
# Decorator
@decorator
def check_db_connection(func, *args, **kwargs):
"""
Für Peewee. db ist eine Instanz der Peewee-Datenbank.
"""
try:
db.get_conn().ping(True)
except:
logging.error(traceback.format_exc())
return func(*args, **kwargs)
@decorator
def check_login(func, *args, **kwargs):
"""
Schreiben Sie den Authentifizierungsprozess und lokalisieren Sie die angemeldete Benutzerinstanz.Steck es in mich oder so.
"""
response_json = func(*args, **kwargs)
return response_json
@decorator
def error_handling(func, *args, **kwargs):
"""
Gibt den Fehler im JSON-Format zurück. Zum Debuggen. Zum Zeitpunkt dieser Version ist ein Fehler aufgetreten_Klasse oder Fehler_Trace löschen.
"""
try:
return func(*args, **kwargs)
except Exception as exception:
if issubclass(exception.__class__, HTTPError):
raise exception
else:
logging.error(traceback.format_exc())
return {
"error_class": type(exception).__name__,
"error_trace": traceback.format_exc(),
}
@decorator
def measurement(func, *args, **kwargs):
"""
Messen Sie die Verarbeitungszeit der API.
"""
start_time = arrow.now()
result = func(*args, **kwargs)
print "Transaction time: {0} secs".format(arrow.now().float_timestamp - start_time.float_timestamp)
return result
# API
# Static files
@route('/')
@route('/<filepath:path>')
def server_static(filepath = None):
if filepath is None:
filepath = 'index.html'
root_path = u"Webstammpfad"
response = static_file(filepath, root = root_path)
return response
# Pull from Bitbucket
@post('/__pull_from_bitbucket')
@error_handling
def pull_from_bitbucket():
"""
Für die Bitbucket-Zusammenarbeit.
Beschränken Sie mit IP den Zugriff auf diese API nur über Bitbucket.
"""
repository_path = "{0}/../../..".format(os.path.dirname(__file__))
repository = Repo(repository_path)
payload = request.json
logging.info("payload: {0}".format(payload))
branch = payload['push']['changes'][0]['new']['name']
logging.info("Pull from Bitbucket: {0}: {1}".format(
branch, repository.active_branch.path))
if repository.active_branch.path.endswith(branch):
repository.remotes[0].pull()
reboot_gunicorn_command = ["/usr/bin/sudo", "/sbin/restart", "api-server"]
output = subprocess.check_output(reboot_gunicorn_command)
logging.info("Reboot API server: {0}: {1}".format(
reboot_gunicorn_command, output))
return {
}
# Pull from GitHub
GITHUB_HOOK_SECRET = os.environ.get('GITHUB_HOOK_SECRET')
@post('/__pull_from_github')
@error_handling
def pull_from_github():
"""
Für die GitHub-Integration.
Fügen Sie den geheimen GitHub Hook-Schlüssel in die Umgebungsvariable ein.
"""
sent_signature = request.headers.get('X-Hub-Signature')[5:]
raw_payload = request.body.read()
generated_signature = hmac.new(GITHUB_HOOK_SECRET, raw_payload, hashlib.sha1).hexdigest()
if sent_signature == generated_signature:
repository_path = "{0}/../../..".format(os.path.dirname(__file__))
repository = Repo(repository_path)
payload = request.json
if payload['ref'] == repository.active_branch.path:
logging.info("Pull from GitHub: {0}: {1}".format(payload['ref'], payload['head_commit']['id']))
repository.remotes[0].pull()
reboot_gunicorn_command = ["/bin/sudo", "/usr/bin/systemctl", "restart", "api_server"]
logging.info("Reboot API server: {0}".format(reboot_gunicorn_command))
return_code = subprocess.call(reboot_gunicorn_command)
return {
}
application = default_app()
if __name__ == '__main__':
run(host = 'localhost', port = 8000, debug = True)
Recommended Posts