This commit is contained in:
Vyacheslav Anzhiganov 2025-01-30 00:10:18 +03:00
parent f310aa46f5
commit ff259a1ae1
4 changed files with 58 additions and 32 deletions

View file

@ -3,4 +3,6 @@ SECRET_KEY = $3cr3tk3y
KOJI_SERVER = https://kojidev.stackwebservices.com/kojihub KOJI_SERVER = https://kojidev.stackwebservices.com/kojihub
KOJI_TARGET = rl9-candidate KOJI_TARGET = rl9-candidate
KOJI_USE_SHELL = true KOJI_USE_SHELL = true
KOJI_NOWAIT = true
KOJI_SCRATCH = true
WEBHOOK_SECRET_KEY = your_secret_key WEBHOOK_SECRET_KEY = your_secret_key

View file

@ -1,5 +1,11 @@
WSGIDaemonProcess forgejo user=builder group=builder processes=2 threads=4 Listen 5001
WSGIScriptAlias /forgejo-webhook /opt/koji-forgejo-webhook/koji_forgejo_webhook.wsgi <VirtualHost *:5001>
<Directory /opt/koji-forgejo-webhook> # ServerName example:5001
Require all granted WSGIDaemonProcess forgejo user=builder group=builder processes=4 threads=4
</Directory> WSGIScriptAlias /forgejo-webhook /opt/koji-forgejo-webhook/koji_forgejo_webhook.wsgi
<Directory /opt/koji-forgejo-webhook>
Require all granted
</Directory>
ErrorLog logs/fwh_error.log
CustomLog logs/fwh_access.log combined
</VirtualHost>

View file

@ -4,20 +4,22 @@ import hmac
import logging import logging
import configparser import configparser
import subprocess import subprocess
from flask import Flask, request, abort from flask import Flask, request, abort, jsonify
import koji import koji
# Load configuration from .ini file # Load configuration from .ini file
config = configparser.ConfigParser() config = configparser.ConfigParser()
config.read('config.ini') config.read('/opt/koji-forgejo-webhook/config.ini')
app = Flask(__name__, instance_relative_config=True) app = Flask(__name__, instance_relative_config=True)
# app.config.from_mapping(config['DEFAULT']) # app.config.from_mapping(config['DEFAULT'])
app.config['DEBUG'] = True
app.config['SECRET_KEY'] = config.get('DEFAULT', 'SECRET_KEY') app.config['SECRET_KEY'] = config.get('DEFAULT', 'SECRET_KEY')
app.config['KOJI_SERVER'] = config.get('DEFAULT', 'KOJI_SERVER') app.config['KOJI_SERVER'] = config.get('DEFAULT', 'KOJI_SERVER')
app.config['KOJI_TARGET'] = config.get('DEFAULT', 'KOJI_TARGET') app.config['KOJI_TARGET'] = config.get('DEFAULT', 'KOJI_TARGET')
app.config['KOJI_USE_SHELL'] = config.getboolean('DEFAULT', 'KOJI_USE_SHELL') app.config['KOJI_USE_SHELL'] = config.getboolean('DEFAULT', 'KOJI_USE_SHELL')
app.config['KOJI_NOWAIT'] = config.getboolean('DEFAULT', 'KOJI_NOWAIT', True) app.config['KOJI_NOWAIT'] = config.getboolean('DEFAULT', 'KOJI_NOWAIT')
app.config['KOJI_SCRATCH'] = config.getboolean('DEFAULT', 'KOJI_SCRATCH')
app.config['WEBHOOK_SECRET_KEY'] = config.get('DEFAULT', 'WEBHOOK_SECRET_KEY') app.config['WEBHOOK_SECRET_KEY'] = config.get('DEFAULT', 'WEBHOOK_SECRET_KEY')
@ -25,21 +27,28 @@ class KojiProcessor:
def __init__(self): def __init__(self):
pass pass
def koji_build_shell(self, build_target, git_url, nowait=True): def koji_build_shell(self, build_target: str, git_url: str, scratch: bool = True, nowait: bool = True) -> str:
try: result = {"out": "", "err": ""}
# Construct the koji build command
nw = '--nowait' if nowait else ''
command = ['koji', 'build', nw, build_target, git_url]
# Construct the koji build command
nw = '--nowait' if nowait else ''
sc = '--scratch' if scratch else ''
command = ['sudo', 'koji', 'build', sc, nw, build_target, git_url]
try:
# Start the build process # Start the build process
result = subprocess.run(command, check=True, capture_output=True, text=True) exec = subprocess.run(' '.join(command), shell=True, capture_output=True, text=True)
result['err'] = exec.stderr
result['out'] = exec.stdout
# Print output from the command # Print output from the command
logging.info(f"Build started successfully!") logging.info(f"Build started successfully!")
logging.info(result.stdout) logging.info(exec.stdout)
except subprocess.CalledProcessError as e: # except subprocess.CalledProcessError as e:
logging.error("Error starting build:") # logging.error("Error starting build:")
logging.error(e.stderr) except Exception as e:
result['err'] = f"{e}"
return result
def koji_build(self, server_url, build_target, source_url, nowait=True): def koji_build(self, server_url, build_target, source_url, nowait=True):
""" """
@ -66,7 +75,6 @@ class KojiProcessor:
'nowait': nowait # Wait for build completion 'nowait': nowait # Wait for build completion
} }
) )
return build_id return build_id
except Exception as e: except Exception as e:
@ -90,6 +98,7 @@ class ForgejoWebhookProcessor:
def process_webhook(self, payload): def process_webhook(self, payload):
"""Process webhook payload""" """Process webhook payload"""
result = dict()
try: try:
data = json.loads(payload) data = json.loads(payload)
@ -104,6 +113,7 @@ class ForgejoWebhookProcessor:
logging.info(f"Branch: {ref}") logging.info(f"Branch: {ref}")
logging.info(f"Number of Commits: {len(commits)}") logging.info(f"Number of Commits: {len(commits)}")
# result = head_commit.get("id")
# Custom processing logic here # Custom processing logic here
# for commit in commits: # for commit in commits:
# logging.info(f"Commit: {commit.get('id')}") # logging.info(f"Commit: {commit.get('id')}")
@ -114,21 +124,31 @@ class ForgejoWebhookProcessor:
git_url = f"git+{clone_url}#{commit_id}" git_url = f"git+{clone_url}#{commit_id}"
if int(app.config.get('KOJI_USE_SHELL')) == 1: if app.config.get('KOJI_USE_SHELL'):
KojiProcessor().koji_build_shell(app.config['KOJI_TARGET'], git_url) result = KojiProcessor().koji_build_shell(app.config['KOJI_TARGET'], git_url)
else: else:
KojiProcessor().koji_build(app.config['KOJI_SERVER'], app.config['KOJI_TARGET'], git_url) result = KojiProcessor().koji_build(app.config['KOJI_SERVER'], app.config['KOJI_TARGET'], git_url)
except json.JSONDecodeError: except json.JSONDecodeError:
logging.error("Invalid JSON payload") logging.error("Invalid JSON payload")
abort(400) abort(400)
return result
@app.route('/', methods=['POST']) @app.route('/ping', methods=['GET'])
@app.route('/forgejo-webhook', methods=['POST']) def ping():
@app.route('/forgejo-webhook/', methods=['POST']) result = subprocess.run('sudo koji moshimoshi', shell=True, capture_output=True, text=True)
stdout = result.stdout
stderr = result.stderr
return jsonify({
"out": f"{stdout}",
"err": f"{stderr}",
})
@app.route('/forgejo', methods=['POST'])
def webhook(): def webhook():
processor = ForgejoWebhookProcessor(app.config['WEBHOOK_SECRET_KEY']) processor = ForgejoWebhookProcessor(app.config.get('WEBHOOK_SECRET_KEY'))
# Get payload and signature # Get payload and signature
payload = request.get_data(as_text=True) payload = request.get_data(as_text=True)
@ -139,11 +159,9 @@ def webhook():
abort(403) abort(403)
# Process webhook # Process webhook
processor.process_webhook(payload) return jsonify(processor.process_webhook(payload))
return 'Webhook processed', 200
if __name__ == '__main__': if __name__ == '__main__':
logging.basicConfig(level=logging.INFO) logging.basicConfig(filename='/opt/koji-forgejo-webhook/error.log', level=logging.DEBUG)
app.run(host="0.0.0.0", port=5001) app.run(host="0.0.0.0", port=5001)

View file

@ -1,7 +1,7 @@
import sys import sys
import logging import logging
logging.basicConfig(stream=sys.stderr) logging.basicConfig(stream=sys.stderr, level=logging.DEBUG)
sys.path.insert(0, "/opt/koji-forgejo-webhook") sys.path.insert(0, "/opt/koji-forgejo-webhook")
from koji_forgejo_webhook import app as application from koji_forgejo_webhook import app as application