mirror of
https://github.com/YunoHost/vinaigrette.git
synced 2024-09-03 20:06:11 +02:00
Adding github webhooks stuff
This commit is contained in:
parent
adacefe6e3
commit
66320bf7be
5 changed files with 274 additions and 4 deletions
20
init.sh
20
init.sh
|
@ -1,5 +1,6 @@
|
||||||
|
|
||||||
apt-get install nginx pbuilder reprepro rebuildd gawk sendxmpp -y
|
apt-get install nginx pbuilder reprepro rebuildd gawk sendxmpp -y
|
||||||
|
apt-get install python-virtualenv python3-pip -y
|
||||||
|
|
||||||
VINAIGRETTE_HOME="/home/vinaigrette"
|
VINAIGRETTE_HOME="/home/vinaigrette"
|
||||||
|
|
||||||
|
@ -16,10 +17,10 @@ git clone https://github.com/yunohost/ssowat
|
||||||
git clone https://github.com/yunohost/moulinette
|
git clone https://github.com/yunohost/moulinette
|
||||||
|
|
||||||
cd yunohost
|
cd yunohost
|
||||||
git symbolic-ref refs/heads/jessie-stable refs/heads/stable
|
git checkout stable && git symbolic-ref refs/heads/jessie-stable refs/heads/stable
|
||||||
git symbolic-ref refs/heads/jessie-testing refs/heads/testing
|
git checkout testing && git symbolic-ref refs/heads/jessie-testing refs/heads/testing
|
||||||
git symbolic-ref refs/heads/jessie-unstable refs/heads/unstable
|
git checkout unstable && git symbolic-ref refs/heads/jessie-unstable refs/heads/unstable
|
||||||
git symbolic-ref refs/heads/stretch-unstable refs/heads/stretch
|
git checkout stretch && git symbolic-ref refs/heads/stretch-unstable refs/heads/stretch
|
||||||
cd ..
|
cd ..
|
||||||
|
|
||||||
mkdir -p /var/www/repo/debian/conf/
|
mkdir -p /var/www/repo/debian/conf/
|
||||||
|
@ -42,3 +43,14 @@ echo "127.0.0.1 $REPO_URL" >> /etc/hosts
|
||||||
service nginx reload
|
service nginx reload
|
||||||
|
|
||||||
rebuildd init
|
rebuildd init
|
||||||
|
|
||||||
|
|
||||||
|
cd $VINAIGRETTE_HOME/webhooks
|
||||||
|
virtualenv venv
|
||||||
|
source venv/bin/activate
|
||||||
|
pip install -r requirements.txt
|
||||||
|
|
||||||
|
cp $VINAIGRETTE_HOME/webhooks/service /etc/init.d/github-webhook
|
||||||
|
systemctl daemon-reload
|
||||||
|
updated-rc.d github-webhook defaults
|
||||||
|
github-webhook
|
||||||
|
|
0
webhooks/logs/.gitkeep
Normal file
0
webhooks/logs/.gitkeep
Normal file
5
webhooks/requirements.txt
Normal file
5
webhooks/requirements.txt
Normal file
|
@ -0,0 +1,5 @@
|
||||||
|
bottle==0.12.9
|
||||||
|
distribute>=0.6.24
|
||||||
|
flup==1.0.3.dev20161029
|
||||||
|
wsgiref==0.1.2
|
||||||
|
urllib>=1.21.1
|
176
webhooks/server.py
Normal file
176
webhooks/server.py
Normal file
|
@ -0,0 +1,176 @@
|
||||||
|
#!/usr/bin/env python3
|
||||||
|
import os
|
||||||
|
import glob
|
||||||
|
import json
|
||||||
|
import time
|
||||||
|
import shutil
|
||||||
|
import tarfile
|
||||||
|
import tempfile
|
||||||
|
import threading
|
||||||
|
import subprocess
|
||||||
|
import collections
|
||||||
|
import urllib.request
|
||||||
|
from queue import Queue
|
||||||
|
|
||||||
|
from bottle import route, request, run
|
||||||
|
|
||||||
|
DISTRIBUTION = "jessie"
|
||||||
|
BRANCHES=['stable', 'testing', 'unstable']
|
||||||
|
|
||||||
|
# -- Variables
|
||||||
|
|
||||||
|
# The backend to use for running the server
|
||||||
|
# See: http://bottlepy.org/docs/0.12/deployment.html#switching-the-server-backend
|
||||||
|
# Note: flup allows to run as FastCGI process
|
||||||
|
SERVER_BACKEND = 'flup'
|
||||||
|
|
||||||
|
# Host and port on which the server will listen
|
||||||
|
HOST = '127.0.0.1'
|
||||||
|
PORT = 9908
|
||||||
|
|
||||||
|
# Path to the script to build a package
|
||||||
|
BUILD_CMD = '/home/vinaigrette/scripts/build_deb'
|
||||||
|
|
||||||
|
# Directory where build logs are stored
|
||||||
|
BUILD_LOG_DIR = '/home/vinaigrette/webhooks/logs'
|
||||||
|
|
||||||
|
# Number of worker threads
|
||||||
|
WORKERS = 1
|
||||||
|
|
||||||
|
# -- Types and methods
|
||||||
|
|
||||||
|
# Represent a new release of a package
|
||||||
|
PackageRelease = collections.namedtuple('PackageRelease', [
|
||||||
|
'name', 'tarball', 'tag', 'branch', 'pid',
|
||||||
|
])
|
||||||
|
|
||||||
|
|
||||||
|
def package_files(tar, pkgname, callback=None):
|
||||||
|
"""Return the members of a package tarball safely."""
|
||||||
|
if not callable(callback):
|
||||||
|
callback = lambda m: None
|
||||||
|
for member in tar:
|
||||||
|
if member.name.startswith(pkgname):
|
||||||
|
callback(member.name)
|
||||||
|
yield member
|
||||||
|
else:
|
||||||
|
callback("nope: " + member.name)
|
||||||
|
|
||||||
|
|
||||||
|
def build(pkg):
|
||||||
|
"""Build the given PackageRelease."""
|
||||||
|
with open(os.path.join(
|
||||||
|
BUILD_LOG_DIR, "{0}.log".format(pkg.pid)), 'w') as logfile:
|
||||||
|
log = lambda m: print(m, file=logfile)
|
||||||
|
log("== Building {0} ==".format(pkg))
|
||||||
|
|
||||||
|
# create a temporary directory for the package
|
||||||
|
pkg_dir = tempfile.mkdtemp()
|
||||||
|
|
||||||
|
# download and extract tarball
|
||||||
|
log(":: Downloading and extract tarball to {0}...".format(pkg_dir))
|
||||||
|
tarball_stream = urllib.request.urlopen(pkg.tarball)
|
||||||
|
tarball = tarfile.open(fileobj=tarball_stream, mode="r|gz")
|
||||||
|
for member in tarball:
|
||||||
|
if member.name[0] not in ['/', '.']:
|
||||||
|
try:
|
||||||
|
_, member.name = member.name.split('/', 1)
|
||||||
|
except ValueError:
|
||||||
|
continue
|
||||||
|
log(member.name)
|
||||||
|
tarball.extract(member, pkg_dir)
|
||||||
|
else:
|
||||||
|
log("ignoring: {0}".format(member.name))
|
||||||
|
tarball.close()
|
||||||
|
|
||||||
|
# build the package
|
||||||
|
log("\n:: Building the Debian package...")
|
||||||
|
logfile.flush()
|
||||||
|
retcode = subprocess.call([
|
||||||
|
BUILD_CMD, '-d', pkg.branch,
|
||||||
|
'-c', DISTRIBUTION, '.'
|
||||||
|
], cwd=pkg_dir, stdout=logfile, stderr=subprocess.STDOUT,
|
||||||
|
)
|
||||||
|
|
||||||
|
# cleaning...
|
||||||
|
shutil.rmtree(pkg_dir)
|
||||||
|
return retcode
|
||||||
|
|
||||||
|
|
||||||
|
def worker():
|
||||||
|
while True:
|
||||||
|
item = queue.get()
|
||||||
|
if item is None:
|
||||||
|
break
|
||||||
|
build(item)
|
||||||
|
queue.task_done()
|
||||||
|
|
||||||
|
|
||||||
|
# -- Web app and routes
|
||||||
|
|
||||||
|
@route("/", method=['GET', 'POST'])
|
||||||
|
def index():
|
||||||
|
if request.method == 'GET':
|
||||||
|
return ' Yolo '
|
||||||
|
|
||||||
|
if request.method == 'POST':
|
||||||
|
|
||||||
|
# Answer to GitHub events
|
||||||
|
if request.headers.get('X-GitHub-Event') == "ping":
|
||||||
|
return json.dumps({'msg': 'Hi!'})
|
||||||
|
|
||||||
|
# Only accept create event:
|
||||||
|
# https://developer.github.com/v3/activity/events/types/#releaseevent
|
||||||
|
if request.headers.get('X-GitHub-Event') != "release":
|
||||||
|
return json.dumps({'msg': "wrong event type"})
|
||||||
|
|
||||||
|
payload = request.json
|
||||||
|
if not payload:
|
||||||
|
return json.dumps({'msg': "invalid payload"})
|
||||||
|
|
||||||
|
# Only handle tag creation (create event also triggers for branch creation)
|
||||||
|
if payload['action'] != "published":
|
||||||
|
return json.dumps({'msg': "uninteresting action"})
|
||||||
|
|
||||||
|
# Validate tag and branch
|
||||||
|
tag = payload['release']['tag_name']
|
||||||
|
if not tag:
|
||||||
|
return json.dumps({'msg': "invalid tag"})
|
||||||
|
branch = payload['release']['target_commitish']
|
||||||
|
if branch not in BRANCHES:
|
||||||
|
return json.dumps({'msg': "uninteresting branch"})
|
||||||
|
|
||||||
|
# Init new package release and put it in the queue
|
||||||
|
package = PackageRelease(
|
||||||
|
name=payload['repository']['name'].lower(),
|
||||||
|
tarball=payload['release']['tarball_url'],
|
||||||
|
tag=tag, branch=branch, pid=int(time.time()),
|
||||||
|
)
|
||||||
|
queue.put(package, False)
|
||||||
|
|
||||||
|
# Return the pid to be able to track building
|
||||||
|
return "Queue id: {0}".format(package.pid)
|
||||||
|
|
||||||
|
|
||||||
|
# -- Main program
|
||||||
|
|
||||||
|
if __name__ == '__main__':
|
||||||
|
# Create the queue and the workers
|
||||||
|
queue = Queue()
|
||||||
|
threads = []
|
||||||
|
for i in range(WORKERS):
|
||||||
|
t = threading.Thread(target=worker)
|
||||||
|
t.start()
|
||||||
|
threads.append(t)
|
||||||
|
|
||||||
|
# Run the Web server
|
||||||
|
run(server=SERVER_BACKEND, host=HOST, port=PORT)
|
||||||
|
|
||||||
|
# Block until all tasks are done
|
||||||
|
queue.join()
|
||||||
|
|
||||||
|
# Stop workers
|
||||||
|
for i in range(WORKERS):
|
||||||
|
queue.put(None)
|
||||||
|
for t in threads:
|
||||||
|
t.join()
|
77
webhooks/service
Normal file
77
webhooks/service
Normal file
|
@ -0,0 +1,77 @@
|
||||||
|
#! /bin/bash
|
||||||
|
# github-webhook init script
|
||||||
|
#
|
||||||
|
### BEGIN INIT INFO
|
||||||
|
# Provides: github-webhook
|
||||||
|
# Required-Start: $remote_fs
|
||||||
|
# Required-Stop: $remote_fs
|
||||||
|
# Should-Start: $network
|
||||||
|
# Should-Stop: $network
|
||||||
|
# Default-Start: 2 3 4 5
|
||||||
|
# Default-Stop: 0 1 6
|
||||||
|
# Short-Description: rebuild daemon
|
||||||
|
# Description: daemon providing rebuild system
|
||||||
|
# for Debian packages
|
||||||
|
### END INIT INFO
|
||||||
|
|
||||||
|
PATH=/home/vinaigrette/scripts/webhooks/venv/bin:/usr/local/sbin:/usr/local/bin:/sbin:/bin:/usr/sbin:/usr/bin
|
||||||
|
DAEMON=/home/vinaitrette/webhooks/server.py
|
||||||
|
NAME=github-webhook
|
||||||
|
DESC="GitHub WebHook daemon"
|
||||||
|
|
||||||
|
GWH_UID=pbuilder
|
||||||
|
GWH_GROUP=pbuilder
|
||||||
|
GWH_CHROOT=/home/vinaigrette/webhooks
|
||||||
|
|
||||||
|
LOGDIR=/var/log/$NAME
|
||||||
|
LOGFILE=$NAME.log
|
||||||
|
|
||||||
|
test -x $DAEMON || exit 0
|
||||||
|
|
||||||
|
# Include github-webhook defaults if available
|
||||||
|
if [ -f /etc/default/github-webhook ] ; then
|
||||||
|
. /etc/default/github-webhook
|
||||||
|
fi
|
||||||
|
|
||||||
|
. /lib/lsb/init-functions
|
||||||
|
set -e
|
||||||
|
|
||||||
|
function do_start {
|
||||||
|
mkdir -p $LOGDIR
|
||||||
|
chown -R $GWH_UID:$GWH_GROUP $LOGDIR
|
||||||
|
|
||||||
|
start-stop-daemon --start --quiet --pidfile /var/run/$NAME.pid \
|
||||||
|
--chuid $GWH_UID:$GWH_GROUP --chdir $GWH_CHROOT \
|
||||||
|
--background --make-pidfile --startas /bin/bash -- -c "exec python $DAEMON >> $LOGDIR/$LOGFILE 2>&1"
|
||||||
|
}
|
||||||
|
|
||||||
|
function do_stop {
|
||||||
|
start-stop-daemon --stop --quiet --oknodo --retry 120 --pidfile /var/run/$NAME.pid
|
||||||
|
}
|
||||||
|
|
||||||
|
case "$1" in
|
||||||
|
start)
|
||||||
|
log_daemon_msg "Starting $DESC" "$NAME"
|
||||||
|
do_start
|
||||||
|
log_end_msg $?
|
||||||
|
;;
|
||||||
|
stop)
|
||||||
|
log_daemon_msg "Stopping $DESC" "$NAME"
|
||||||
|
do_stop
|
||||||
|
log_end_msg $?
|
||||||
|
;;
|
||||||
|
restart)
|
||||||
|
log_daemon_msg "Restarting $DESC" "$NAME"
|
||||||
|
do_stop
|
||||||
|
sleep 1
|
||||||
|
do_start
|
||||||
|
log_end_msg $?
|
||||||
|
;;
|
||||||
|
*)
|
||||||
|
N=/etc/init.d/$NAME
|
||||||
|
echo "Usage: $N {start|stop|restart}" >&2
|
||||||
|
exit 1
|
||||||
|
;;
|
||||||
|
esac
|
||||||
|
|
||||||
|
exit 0
|
Loading…
Reference in a new issue