Add missing docker builders
This commit is contained in:
parent
a802ecce7a
commit
4032ad5882
8
docker/apache_docker/Dockerfile
Normal file
8
docker/apache_docker/Dockerfile
Normal file
@ -0,0 +1,8 @@
|
||||
FROM php:8.2-apache
|
||||
|
||||
RUN apt-get update && apt-get install -y zlib1g-dev libwebp-dev libavif-dev libpng-dev libjpeg-dev libzip-dev ruby && rm -rf /var/lib/apt/lists/*
|
||||
|
||||
RUN gem install kramdown
|
||||
|
||||
RUN docker-php-ext-install pdo pdo_mysql gd zip
|
||||
RUN a2enmod rewrite
|
3
docker/apache_docker/builder.sh
Normal file
3
docker/apache_docker/builder.sh
Normal file
@ -0,0 +1,3 @@
|
||||
podman pull php:8.2-apache
|
||||
podman build -t glvx/php .
|
||||
podman push glvx/php docker://docker.io/glvx/php:8.2b
|
14
docker/deployer_docker/Dockerfile
Normal file
14
docker/deployer_docker/Dockerfile
Normal file
@ -0,0 +1,14 @@
|
||||
FROM ubuntu:24.04
|
||||
|
||||
|
||||
RUN apt-get update && apt-get install --no-upgrade -y curl python3 python3-pip python3-venv git git-lfs ssh
|
||||
COPY updater.sh /updater.sh
|
||||
COPY webhook /opt/webhook
|
||||
|
||||
RUN python3 -m venv /opt/webhook/.venv && \
|
||||
/opt/webhook/.venv/bin/python3 -m ensurepip && \
|
||||
/opt/webhook/.venv/bin/python3 -m pip install -r /opt/webhook/requirements.txt
|
||||
|
||||
COPY webhook-runner.sh /webhook-runner.sh
|
||||
|
||||
ENTRYPOINT /updater.sh
|
2
docker/deployer_docker/builder.sh
Normal file
2
docker/deployer_docker/builder.sh
Normal file
@ -0,0 +1,2 @@
|
||||
podman build -t glvx/web-updater .
|
||||
podman push glvx/web-updater docker://docker.io/glvx/web-updater:241204-2
|
24
docker/deployer_docker/updater.sh
Executable file
24
docker/deployer_docker/updater.sh
Executable file
@ -0,0 +1,24 @@
|
||||
#!/bin/bash
|
||||
|
||||
|
||||
if test -z "${GL_URL}"; then
|
||||
echo "No URL defined"
|
||||
exit 1
|
||||
fi
|
||||
|
||||
test -d /web/.attic || mkdir /web/.attic
|
||||
|
||||
if test -f /web/.attic/SNAPID; then
|
||||
read snapid < /web/.attic/SNAPID
|
||||
let snapid=snapid+1
|
||||
echo ${snapid} > /web/.attic/SNAPID
|
||||
mkdir /web/.attic/snap-${snapid}
|
||||
else
|
||||
echo 0 > /web/.attic/SNAPID
|
||||
let snapid=0
|
||||
mkdir /web/.attic/snap-${snapid}
|
||||
fi
|
||||
|
||||
find /web -maxdepth 1 ! "(" -name ".attic" -o -wholename "/web" ")" -print0 | xargs -n 1 -0 mv -t /web/.attic/snap-${snapid}
|
||||
|
||||
curl "${GL_URL}" | tar -C /web --strip-components 1 -zxvf -
|
9
docker/deployer_docker/webhook-runner.sh
Executable file
9
docker/deployer_docker/webhook-runner.sh
Executable file
@ -0,0 +1,9 @@
|
||||
#!/bin/bash
|
||||
|
||||
GIT_AUTH_MODE=$1
|
||||
|
||||
export GIT_AUTH_MODE
|
||||
|
||||
source /opt/webhook/.venv/bin/activate
|
||||
cd /opt/webhook
|
||||
gunicorn --bind 0.0.0.0:8000 gitea-webhook-handler:app
|
343
docker/deployer_docker/webhook/gitea-webhook-handler.py
Normal file
343
docker/deployer_docker/webhook/gitea-webhook-handler.py
Normal file
@ -0,0 +1,343 @@
|
||||
from flask import Flask, request, jsonify
|
||||
import hmac
|
||||
import hashlib
|
||||
import os
|
||||
from functools import wraps
|
||||
import base64
|
||||
import logging
|
||||
import subprocess
|
||||
from datetime import datetime
|
||||
from enum import Enum
|
||||
|
||||
app = Flask(__name__)
|
||||
|
||||
# Configuration
|
||||
# In production, use proper secret management
|
||||
WEBHOOK_SECRET = os.environ['WEBHOOK_SECRET']
|
||||
API_USERNAME = os.environ['API_USERNAME']
|
||||
API_PASSWORD = os.environ['API_PASSWORD']
|
||||
DATA_DIR = os.environ['DATA_DIR']
|
||||
GIT_AUTH_MODE = os.environ['GIT_AUTH_MODE']
|
||||
|
||||
if GIT_AUTH_MODE == 'http':
|
||||
auth_option = []
|
||||
elif GIT_AUTH_MODE == 'ssh':
|
||||
auth_option = ['--config core.sshCommand="ssh -i /ssh/ssh-key" -o StrictHostKeyChecking=accept-new']
|
||||
else:
|
||||
raise ValueError("Invalid GIT_AUTH_MODE")
|
||||
|
||||
# Setup logging
|
||||
logging.basicConfig(
|
||||
level=logging.INFO,
|
||||
format='%(asctime)s - %(levelname)s - %(message)s',
|
||||
handlers=[
|
||||
logging.FileHandler('webhook.log'),
|
||||
logging.StreamHandler()
|
||||
]
|
||||
)
|
||||
logger = logging.getLogger(__name__)
|
||||
|
||||
class GitProvider(Enum):
|
||||
GITEA = "gitea"
|
||||
GITLAB = "gitlab"
|
||||
UNKNOWN = "unknown"
|
||||
|
||||
|
||||
GITEA_EVENTS = {
|
||||
'push': 'Push events',
|
||||
'create': 'Branch or tag creation',
|
||||
'delete': 'Branch or tag deletion',
|
||||
'pull_request': 'Pull request events',
|
||||
'issues': 'Issues events'
|
||||
}
|
||||
|
||||
|
||||
class GitOperationError(Exception):
|
||||
"""Custom exception for git operations"""
|
||||
pass
|
||||
|
||||
|
||||
def detect_git_provider():
|
||||
"""
|
||||
Detect whether the webhook is from Gitea or GitLab based on headers
|
||||
"""
|
||||
if request.headers.get('X-Gitea-Event'):
|
||||
return GitProvider.GITEA
|
||||
elif request.headers.get('X-Gitlab-Event'):
|
||||
return GitProvider.GITLAB
|
||||
return GitProvider.UNKNOWN
|
||||
|
||||
|
||||
def verify_signature(f):
|
||||
@wraps(f)
|
||||
def decorated_function(*args, **kwargs):
|
||||
provider = detect_git_provider()
|
||||
payload_body = request.get_data()
|
||||
|
||||
if provider == GitProvider.GITEA:
|
||||
signature = request.headers.get('X-Gitea-Signature')
|
||||
if not signature:
|
||||
return jsonify({'error': 'No Gitea signature provided'}), 401
|
||||
|
||||
expected_signature = hmac.new(
|
||||
WEBHOOK_SECRET.encode('utf-8'),
|
||||
payload_body,
|
||||
hashlib.sha256
|
||||
).hexdigest()
|
||||
|
||||
if not hmac.compare_digest(signature, expected_signature):
|
||||
return jsonify({'error': 'Invalid Gitea signature'}), 401
|
||||
|
||||
elif provider == GitProvider.GITLAB:
|
||||
token = request.headers.get('X-Gitlab-Token')
|
||||
if not token:
|
||||
return jsonify({'error': 'No GitLab token provided'}), 401
|
||||
|
||||
if not hmac.compare_digest(token, WEBHOOK_SECRET):
|
||||
return jsonify({'error': 'Invalid GitLab token'}), 401
|
||||
|
||||
else:
|
||||
return jsonify({'error': 'Unknown Git provider'}), 400
|
||||
|
||||
return f(*args, **kwargs)
|
||||
return decorated_function
|
||||
|
||||
def execute_git_pull(repo_path):
|
||||
"""
|
||||
Execute git pull in the specified repository path
|
||||
Returns tuple of (success, message)
|
||||
"""
|
||||
try:
|
||||
# Verify the directory exists and is a git repository
|
||||
if not os.path.exists(repo_path):
|
||||
raise GitOperationError(f"Directory does not exist: {repo_path}")
|
||||
|
||||
if not os.path.exists(os.path.join(repo_path, '.git')):
|
||||
raise GitOperationError(f"Not a git repository: {repo_path}")
|
||||
|
||||
# Create backup of current state
|
||||
current_commit = subprocess.check_output(
|
||||
['git', 'rev-parse', 'HEAD'],
|
||||
cwd=repo_path,
|
||||
stderr=subprocess.PIPE
|
||||
).decode().strip()
|
||||
|
||||
# Execute git pull
|
||||
result = subprocess.run(
|
||||
['git', 'pull'] + auth_option,
|
||||
cwd=repo_path,
|
||||
capture_output=True,
|
||||
text=True,
|
||||
timeout=300 # 5-minute timeout
|
||||
)
|
||||
|
||||
if result.returncode != 0:
|
||||
raise GitOperationError(f"Git pull failed: {result.stderr}")
|
||||
|
||||
new_commit = subprocess.check_output(
|
||||
['git', 'rev-parse', 'HEAD'],
|
||||
cwd=repo_path,
|
||||
stderr=subprocess.PIPE
|
||||
).decode().strip()
|
||||
|
||||
return True, {
|
||||
'message': 'Git pull successful',
|
||||
'output': result.stdout,
|
||||
'previous_commit': current_commit,
|
||||
'new_commit': new_commit
|
||||
}
|
||||
|
||||
except subprocess.TimeoutExpired:
|
||||
raise GitOperationError("Git pull operation timed out")
|
||||
except subprocess.CalledProcessError as e:
|
||||
raise GitOperationError(f"Git command failed: {e.stderr.decode() if e.stderr else str(e)}")
|
||||
except Exception as e:
|
||||
raise GitOperationError(f"Unexpected error: {str(e)}")
|
||||
|
||||
|
||||
def require_basic_auth(f):
|
||||
@wraps(f)
|
||||
def decorated_function(*args, **kwargs):
|
||||
auth_header = request.headers.get('Authorization')
|
||||
if not auth_header:
|
||||
return authenticate()
|
||||
|
||||
try:
|
||||
auth_type, auth_string = auth_header.split(' ', 1)
|
||||
if auth_type.lower() != 'basic':
|
||||
return authenticate()
|
||||
|
||||
# Decode base64 credentials
|
||||
credentials = base64.b64decode(auth_string).decode('utf-8')
|
||||
username, password = credentials.split(':', 1)
|
||||
|
||||
if not (username == API_USERNAME and password == API_PASSWORD):
|
||||
return authenticate()
|
||||
|
||||
except (ValueError, base64.binascii.Error):
|
||||
return authenticate()
|
||||
|
||||
return f(*args, **kwargs)
|
||||
return decorated_function
|
||||
|
||||
def authenticate():
|
||||
"""Sends a 401 response that enables basic auth"""
|
||||
return jsonify({'error': 'Authentication required'}), 401, {
|
||||
'WWW-Authenticate': 'Basic realm="Login Required"'
|
||||
}
|
||||
|
||||
|
||||
def parse_push_event(provider, payload):
|
||||
"""
|
||||
Parse push event payload based on the provider
|
||||
Returns standardized data structure
|
||||
"""
|
||||
try:
|
||||
if provider == GitProvider.GITEA:
|
||||
return {
|
||||
'repo_name': payload['repository']['full_name'].split('/')[-1],
|
||||
'repo_full_name': payload['repository']['full_name'],
|
||||
'branch': payload['ref'].split('/')[-1],
|
||||
'commits': payload['commits'],
|
||||
'default_branch': payload['repository']['default_branch']
|
||||
}
|
||||
elif provider == GitProvider.GITLAB:
|
||||
return {
|
||||
'repo_name': payload['project']['web_url'].split('/')[-1],
|
||||
'repo_full_name': payload['project']['name'],
|
||||
'branch': payload['ref'].split('/')[-1],
|
||||
'commits': payload['commits'],
|
||||
'default_branch': payload['project']['default_branch']
|
||||
}
|
||||
else:
|
||||
raise ValueError("Unknown git provider")
|
||||
except KeyError as e:
|
||||
raise KeyError(f"Missing required field in payload: {str(e)}")
|
||||
|
||||
|
||||
@app.route('/webhook', methods=['POST'])
|
||||
@require_basic_auth
|
||||
@verify_signature
|
||||
def webhook():
|
||||
if not request.is_json:
|
||||
return jsonify({'error': 'Content type must be application/json'}), 400
|
||||
|
||||
provider = detect_git_provider()
|
||||
payload = request.get_json()
|
||||
|
||||
# Determine event type based on provider
|
||||
if provider == GitProvider.GITEA:
|
||||
event_type = request.headers.get('X-Gitea-Event')
|
||||
elif provider == GitProvider.GITLAB:
|
||||
event_type = request.headers.get('X-Gitlab-Event')
|
||||
else:
|
||||
return jsonify({'error': 'Unknown git provider'}), 400
|
||||
|
||||
# Normalize event types between Gitea and GitLab
|
||||
if provider == GitProvider.GITLAB and event_type == 'Push Hook':
|
||||
event_type = 'push'
|
||||
|
||||
if event_type.lower() == 'push':
|
||||
return handle_push(provider, payload)
|
||||
else:
|
||||
logger.info(f"Received unhandled event type: {event_type} from {provider.value}")
|
||||
return jsonify({'status': 'received', 'event': event_type, 'provider': provider.value}), 200
|
||||
|
||||
|
||||
def handle_push(provider, payload):
|
||||
"""Handle push events"""
|
||||
try:
|
||||
# Parse the payload according to the provider's format
|
||||
data = parse_push_event(provider, payload)
|
||||
|
||||
logger.info(f"Push to {data['repo_full_name']} on branch {data['branch']} via {provider.value}")
|
||||
logger.info(f"Number of commits: {len(data['commits'])}")
|
||||
|
||||
# Only process pushes to the default branch
|
||||
if data['branch'] != data['default_branch']:
|
||||
logger.info(f"Skipping pull for non-default branch: {data['branch']}")
|
||||
return jsonify({
|
||||
'status': 'skipped',
|
||||
'event': 'push',
|
||||
'provider': provider.value,
|
||||
'reason': f"Push was to non-default branch {data['branch']}"
|
||||
}), 200
|
||||
|
||||
|
||||
# Construct the repository path
|
||||
repo_path = DATA_DIR #os.path.join(DATA_DIR, data['repo_name'])
|
||||
|
||||
try:
|
||||
success, result = execute_git_pull(repo_path)
|
||||
logger.info(f"Git pull result for {data['repo_name']}: {result['message']}")
|
||||
|
||||
response_data = {
|
||||
'status': 'success',
|
||||
'event': 'push',
|
||||
'provider': provider.value,
|
||||
'repo': data['repo_full_name'],
|
||||
'branch': data['branch'],
|
||||
'commits_count': len(data['commits']),
|
||||
'git_pull': result
|
||||
}
|
||||
|
||||
except GitOperationError as e:
|
||||
logger.error(f"Git pull failed for {data['repo_name']}: {str(e)}")
|
||||
response_data = {
|
||||
'status': 'error',
|
||||
'event': 'push',
|
||||
'provider': provider.value,
|
||||
'repo': data['repo_full_name'],
|
||||
'branch': data['branch'],
|
||||
'commits_count': len(data['commits']),
|
||||
'error': str(e)
|
||||
}
|
||||
|
||||
return jsonify(response_data), 200
|
||||
|
||||
except KeyError as e:
|
||||
logger.error(f"Invalid payload structure: {str(e)}")
|
||||
return jsonify({'error': f'Invalid payload structure: {str(e)}'}), 400
|
||||
|
||||
#def handle_pull_request(payload):
|
||||
# """Handle pull request events"""
|
||||
# try:
|
||||
# action = payload['action']
|
||||
# pr_number = payload['number']
|
||||
# repo = payload['repository']['full_name']
|
||||
#
|
||||
# logger.info(f"Pull request #{pr_number} {action} in {repo}")
|
||||
#
|
||||
# return jsonify({
|
||||
# 'status': 'success',
|
||||
# 'event': 'pull_request',
|
||||
# 'action': action,
|
||||
# 'pr_number': pr_number,
|
||||
# 'repo': repo
|
||||
# }), 200
|
||||
# except KeyError as e:
|
||||
# logger.error(f"Invalid payload structure: {str(e)}")
|
||||
# return jsonify({'error': f'Invalid payload structure: {str(e)}'}), 400
|
||||
#
|
||||
#def handle_issues(payload):
|
||||
# """Handle issues events"""
|
||||
# try:
|
||||
# action = payload['action']
|
||||
# issue_number = payload['issue']['number']
|
||||
# repo = payload['repository']['full_name']
|
||||
#
|
||||
# logger.info(f"Issue #{issue_number} {action} in {repo}")
|
||||
#
|
||||
# return jsonify({
|
||||
# 'status': 'success',
|
||||
# 'event': 'issues',
|
||||
# 'action': action,
|
||||
# 'issue_number': issue_number,
|
||||
# 'repo': repo
|
||||
# }), 200
|
||||
# except KeyError as e:
|
||||
# logger.error(f"Invalid payload structure: {str(e)}")
|
||||
# return jsonify({'error': f'Invalid payload structure: {str(e)}'}), 400
|
||||
|
||||
if __name__ == '__main__':
|
||||
app.run(host='0.0.0.0', port=5000)
|
211
docker/deployer_docker/webhook/poetry.lock
generated
Normal file
211
docker/deployer_docker/webhook/poetry.lock
generated
Normal file
@ -0,0 +1,211 @@
|
||||
# This file is automatically @generated by Poetry 1.8.3 and should not be changed by hand.
|
||||
|
||||
[[package]]
|
||||
name = "blinker"
|
||||
version = "1.9.0"
|
||||
description = "Fast, simple object-to-object and broadcast signaling"
|
||||
optional = false
|
||||
python-versions = ">=3.9"
|
||||
files = [
|
||||
{file = "blinker-1.9.0-py3-none-any.whl", hash = "sha256:ba0efaa9080b619ff2f3459d1d500c57bddea4a6b424b60a91141db6fd2f08bc"},
|
||||
{file = "blinker-1.9.0.tar.gz", hash = "sha256:b4ce2265a7abece45e7cc896e98dbebe6cead56bcf805a3d23136d145f5445bf"},
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "click"
|
||||
version = "8.1.7"
|
||||
description = "Composable command line interface toolkit"
|
||||
optional = false
|
||||
python-versions = ">=3.7"
|
||||
files = [
|
||||
{file = "click-8.1.7-py3-none-any.whl", hash = "sha256:ae74fb96c20a0277a1d615f1e4d73c8414f5a98db8b799a7931d1582f3390c28"},
|
||||
{file = "click-8.1.7.tar.gz", hash = "sha256:ca9853ad459e787e2192211578cc907e7594e294c7ccc834310722b41b9ca6de"},
|
||||
]
|
||||
|
||||
[package.dependencies]
|
||||
colorama = {version = "*", markers = "platform_system == \"Windows\""}
|
||||
|
||||
[[package]]
|
||||
name = "colorama"
|
||||
version = "0.4.6"
|
||||
description = "Cross-platform colored terminal text."
|
||||
optional = false
|
||||
python-versions = "!=3.0.*,!=3.1.*,!=3.2.*,!=3.3.*,!=3.4.*,!=3.5.*,!=3.6.*,>=2.7"
|
||||
files = [
|
||||
{file = "colorama-0.4.6-py2.py3-none-any.whl", hash = "sha256:4f1d9991f5acc0ca119f9d443620b77f9d6b33703e51011c16baf57afb285fc6"},
|
||||
{file = "colorama-0.4.6.tar.gz", hash = "sha256:08695f5cb7ed6e0531a20572697297273c47b8cae5a63ffc6d6ed5c201be6e44"},
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "flask"
|
||||
version = "3.1.0"
|
||||
description = "A simple framework for building complex web applications."
|
||||
optional = false
|
||||
python-versions = ">=3.9"
|
||||
files = [
|
||||
{file = "flask-3.1.0-py3-none-any.whl", hash = "sha256:d667207822eb83f1c4b50949b1623c8fc8d51f2341d65f72e1a1815397551136"},
|
||||
{file = "flask-3.1.0.tar.gz", hash = "sha256:5f873c5184c897c8d9d1b05df1e3d01b14910ce69607a117bd3277098a5836ac"},
|
||||
]
|
||||
|
||||
[package.dependencies]
|
||||
blinker = ">=1.9"
|
||||
click = ">=8.1.3"
|
||||
itsdangerous = ">=2.2"
|
||||
Jinja2 = ">=3.1.2"
|
||||
Werkzeug = ">=3.1"
|
||||
|
||||
[package.extras]
|
||||
async = ["asgiref (>=3.2)"]
|
||||
dotenv = ["python-dotenv"]
|
||||
|
||||
[[package]]
|
||||
name = "gunicorn"
|
||||
version = "23.0.0"
|
||||
description = "WSGI HTTP Server for UNIX"
|
||||
optional = false
|
||||
python-versions = ">=3.7"
|
||||
files = [
|
||||
{file = "gunicorn-23.0.0-py3-none-any.whl", hash = "sha256:ec400d38950de4dfd418cff8328b2c8faed0edb0d517d3394e457c317908ca4d"},
|
||||
{file = "gunicorn-23.0.0.tar.gz", hash = "sha256:f014447a0101dc57e294f6c18ca6b40227a4c90e9bdb586042628030cba004ec"},
|
||||
]
|
||||
|
||||
[package.dependencies]
|
||||
packaging = "*"
|
||||
|
||||
[package.extras]
|
||||
eventlet = ["eventlet (>=0.24.1,!=0.36.0)"]
|
||||
gevent = ["gevent (>=1.4.0)"]
|
||||
setproctitle = ["setproctitle"]
|
||||
testing = ["coverage", "eventlet", "gevent", "pytest", "pytest-cov"]
|
||||
tornado = ["tornado (>=0.2)"]
|
||||
|
||||
[[package]]
|
||||
name = "itsdangerous"
|
||||
version = "2.2.0"
|
||||
description = "Safely pass data to untrusted environments and back."
|
||||
optional = false
|
||||
python-versions = ">=3.8"
|
||||
files = [
|
||||
{file = "itsdangerous-2.2.0-py3-none-any.whl", hash = "sha256:c6242fc49e35958c8b15141343aa660db5fc54d4f13a1db01a3f5891b98700ef"},
|
||||
{file = "itsdangerous-2.2.0.tar.gz", hash = "sha256:e0050c0b7da1eea53ffaf149c0cfbb5c6e2e2b69c4bef22c81fa6eb73e5f6173"},
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "jinja2"
|
||||
version = "3.1.4"
|
||||
description = "A very fast and expressive template engine."
|
||||
optional = false
|
||||
python-versions = ">=3.7"
|
||||
files = [
|
||||
{file = "jinja2-3.1.4-py3-none-any.whl", hash = "sha256:bc5dd2abb727a5319567b7a813e6a2e7318c39f4f487cfe6c89c6f9c7d25197d"},
|
||||
{file = "jinja2-3.1.4.tar.gz", hash = "sha256:4a3aee7acbbe7303aede8e9648d13b8bf88a429282aa6122a993f0ac800cb369"},
|
||||
]
|
||||
|
||||
[package.dependencies]
|
||||
MarkupSafe = ">=2.0"
|
||||
|
||||
[package.extras]
|
||||
i18n = ["Babel (>=2.7)"]
|
||||
|
||||
[[package]]
|
||||
name = "markupsafe"
|
||||
version = "3.0.2"
|
||||
description = "Safely add untrusted strings to HTML/XML markup."
|
||||
optional = false
|
||||
python-versions = ">=3.9"
|
||||
files = [
|
||||
{file = "MarkupSafe-3.0.2-cp310-cp310-macosx_10_9_universal2.whl", hash = "sha256:7e94c425039cde14257288fd61dcfb01963e658efbc0ff54f5306b06054700f8"},
|
||||
{file = "MarkupSafe-3.0.2-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:9e2d922824181480953426608b81967de705c3cef4d1af983af849d7bd619158"},
|
||||
{file = "MarkupSafe-3.0.2-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:38a9ef736c01fccdd6600705b09dc574584b89bea478200c5fbf112a6b0d5579"},
|
||||
{file = "MarkupSafe-3.0.2-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:bbcb445fa71794da8f178f0f6d66789a28d7319071af7a496d4d507ed566270d"},
|
||||
{file = "MarkupSafe-3.0.2-cp310-cp310-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:57cb5a3cf367aeb1d316576250f65edec5bb3be939e9247ae594b4bcbc317dfb"},
|
||||
{file = "MarkupSafe-3.0.2-cp310-cp310-musllinux_1_2_aarch64.whl", hash = "sha256:3809ede931876f5b2ec92eef964286840ed3540dadf803dd570c3b7e13141a3b"},
|
||||
{file = "MarkupSafe-3.0.2-cp310-cp310-musllinux_1_2_i686.whl", hash = "sha256:e07c3764494e3776c602c1e78e298937c3315ccc9043ead7e685b7f2b8d47b3c"},
|
||||
{file = "MarkupSafe-3.0.2-cp310-cp310-musllinux_1_2_x86_64.whl", hash = "sha256:b424c77b206d63d500bcb69fa55ed8d0e6a3774056bdc4839fc9298a7edca171"},
|
||||
{file = "MarkupSafe-3.0.2-cp310-cp310-win32.whl", hash = "sha256:fcabf5ff6eea076f859677f5f0b6b5c1a51e70a376b0579e0eadef8db48c6b50"},
|
||||
{file = "MarkupSafe-3.0.2-cp310-cp310-win_amd64.whl", hash = "sha256:6af100e168aa82a50e186c82875a5893c5597a0c1ccdb0d8b40240b1f28b969a"},
|
||||
{file = "MarkupSafe-3.0.2-cp311-cp311-macosx_10_9_universal2.whl", hash = "sha256:9025b4018f3a1314059769c7bf15441064b2207cb3f065e6ea1e7359cb46db9d"},
|
||||
{file = "MarkupSafe-3.0.2-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:93335ca3812df2f366e80509ae119189886b0f3c2b81325d39efdb84a1e2ae93"},
|
||||
{file = "MarkupSafe-3.0.2-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:2cb8438c3cbb25e220c2ab33bb226559e7afb3baec11c4f218ffa7308603c832"},
|
||||
{file = "MarkupSafe-3.0.2-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:a123e330ef0853c6e822384873bef7507557d8e4a082961e1defa947aa59ba84"},
|
||||
{file = "MarkupSafe-3.0.2-cp311-cp311-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:1e084f686b92e5b83186b07e8a17fc09e38fff551f3602b249881fec658d3eca"},
|
||||
{file = "MarkupSafe-3.0.2-cp311-cp311-musllinux_1_2_aarch64.whl", hash = "sha256:d8213e09c917a951de9d09ecee036d5c7d36cb6cb7dbaece4c71a60d79fb9798"},
|
||||
{file = "MarkupSafe-3.0.2-cp311-cp311-musllinux_1_2_i686.whl", hash = "sha256:5b02fb34468b6aaa40dfc198d813a641e3a63b98c2b05a16b9f80b7ec314185e"},
|
||||
{file = "MarkupSafe-3.0.2-cp311-cp311-musllinux_1_2_x86_64.whl", hash = "sha256:0bff5e0ae4ef2e1ae4fdf2dfd5b76c75e5c2fa4132d05fc1b0dabcd20c7e28c4"},
|
||||
{file = "MarkupSafe-3.0.2-cp311-cp311-win32.whl", hash = "sha256:6c89876f41da747c8d3677a2b540fb32ef5715f97b66eeb0c6b66f5e3ef6f59d"},
|
||||
{file = "MarkupSafe-3.0.2-cp311-cp311-win_amd64.whl", hash = "sha256:70a87b411535ccad5ef2f1df5136506a10775d267e197e4cf531ced10537bd6b"},
|
||||
{file = "MarkupSafe-3.0.2-cp312-cp312-macosx_10_13_universal2.whl", hash = "sha256:9778bd8ab0a994ebf6f84c2b949e65736d5575320a17ae8984a77fab08db94cf"},
|
||||
{file = "MarkupSafe-3.0.2-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:846ade7b71e3536c4e56b386c2a47adf5741d2d8b94ec9dc3e92e5e1ee1e2225"},
|
||||
{file = "MarkupSafe-3.0.2-cp312-cp312-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:1c99d261bd2d5f6b59325c92c73df481e05e57f19837bdca8413b9eac4bd8028"},
|
||||
{file = "MarkupSafe-3.0.2-cp312-cp312-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:e17c96c14e19278594aa4841ec148115f9c7615a47382ecb6b82bd8fea3ab0c8"},
|
||||
{file = "MarkupSafe-3.0.2-cp312-cp312-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:88416bd1e65dcea10bc7569faacb2c20ce071dd1f87539ca2ab364bf6231393c"},
|
||||
{file = "MarkupSafe-3.0.2-cp312-cp312-musllinux_1_2_aarch64.whl", hash = "sha256:2181e67807fc2fa785d0592dc2d6206c019b9502410671cc905d132a92866557"},
|
||||
{file = "MarkupSafe-3.0.2-cp312-cp312-musllinux_1_2_i686.whl", hash = "sha256:52305740fe773d09cffb16f8ed0427942901f00adedac82ec8b67752f58a1b22"},
|
||||
{file = "MarkupSafe-3.0.2-cp312-cp312-musllinux_1_2_x86_64.whl", hash = "sha256:ad10d3ded218f1039f11a75f8091880239651b52e9bb592ca27de44eed242a48"},
|
||||
{file = "MarkupSafe-3.0.2-cp312-cp312-win32.whl", hash = "sha256:0f4ca02bea9a23221c0182836703cbf8930c5e9454bacce27e767509fa286a30"},
|
||||
{file = "MarkupSafe-3.0.2-cp312-cp312-win_amd64.whl", hash = "sha256:8e06879fc22a25ca47312fbe7c8264eb0b662f6db27cb2d3bbbc74b1df4b9b87"},
|
||||
{file = "MarkupSafe-3.0.2-cp313-cp313-macosx_10_13_universal2.whl", hash = "sha256:ba9527cdd4c926ed0760bc301f6728ef34d841f405abf9d4f959c478421e4efd"},
|
||||
{file = "MarkupSafe-3.0.2-cp313-cp313-macosx_11_0_arm64.whl", hash = "sha256:f8b3d067f2e40fe93e1ccdd6b2e1d16c43140e76f02fb1319a05cf2b79d99430"},
|
||||
{file = "MarkupSafe-3.0.2-cp313-cp313-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:569511d3b58c8791ab4c2e1285575265991e6d8f8700c7be0e88f86cb0672094"},
|
||||
{file = "MarkupSafe-3.0.2-cp313-cp313-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:15ab75ef81add55874e7ab7055e9c397312385bd9ced94920f2802310c930396"},
|
||||
{file = "MarkupSafe-3.0.2-cp313-cp313-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:f3818cb119498c0678015754eba762e0d61e5b52d34c8b13d770f0719f7b1d79"},
|
||||
{file = "MarkupSafe-3.0.2-cp313-cp313-musllinux_1_2_aarch64.whl", hash = "sha256:cdb82a876c47801bb54a690c5ae105a46b392ac6099881cdfb9f6e95e4014c6a"},
|
||||
{file = "MarkupSafe-3.0.2-cp313-cp313-musllinux_1_2_i686.whl", hash = "sha256:cabc348d87e913db6ab4aa100f01b08f481097838bdddf7c7a84b7575b7309ca"},
|
||||
{file = "MarkupSafe-3.0.2-cp313-cp313-musllinux_1_2_x86_64.whl", hash = "sha256:444dcda765c8a838eaae23112db52f1efaf750daddb2d9ca300bcae1039adc5c"},
|
||||
{file = "MarkupSafe-3.0.2-cp313-cp313-win32.whl", hash = "sha256:bcf3e58998965654fdaff38e58584d8937aa3096ab5354d493c77d1fdd66d7a1"},
|
||||
{file = "MarkupSafe-3.0.2-cp313-cp313-win_amd64.whl", hash = "sha256:e6a2a455bd412959b57a172ce6328d2dd1f01cb2135efda2e4576e8a23fa3b0f"},
|
||||
{file = "MarkupSafe-3.0.2-cp313-cp313t-macosx_10_13_universal2.whl", hash = "sha256:b5a6b3ada725cea8a5e634536b1b01c30bcdcd7f9c6fff4151548d5bf6b3a36c"},
|
||||
{file = "MarkupSafe-3.0.2-cp313-cp313t-macosx_11_0_arm64.whl", hash = "sha256:a904af0a6162c73e3edcb969eeeb53a63ceeb5d8cf642fade7d39e7963a22ddb"},
|
||||
{file = "MarkupSafe-3.0.2-cp313-cp313t-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:4aa4e5faecf353ed117801a068ebab7b7e09ffb6e1d5e412dc852e0da018126c"},
|
||||
{file = "MarkupSafe-3.0.2-cp313-cp313t-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:c0ef13eaeee5b615fb07c9a7dadb38eac06a0608b41570d8ade51c56539e509d"},
|
||||
{file = "MarkupSafe-3.0.2-cp313-cp313t-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:d16a81a06776313e817c951135cf7340a3e91e8c1ff2fac444cfd75fffa04afe"},
|
||||
{file = "MarkupSafe-3.0.2-cp313-cp313t-musllinux_1_2_aarch64.whl", hash = "sha256:6381026f158fdb7c72a168278597a5e3a5222e83ea18f543112b2662a9b699c5"},
|
||||
{file = "MarkupSafe-3.0.2-cp313-cp313t-musllinux_1_2_i686.whl", hash = "sha256:3d79d162e7be8f996986c064d1c7c817f6df3a77fe3d6859f6f9e7be4b8c213a"},
|
||||
{file = "MarkupSafe-3.0.2-cp313-cp313t-musllinux_1_2_x86_64.whl", hash = "sha256:131a3c7689c85f5ad20f9f6fb1b866f402c445b220c19fe4308c0b147ccd2ad9"},
|
||||
{file = "MarkupSafe-3.0.2-cp313-cp313t-win32.whl", hash = "sha256:ba8062ed2cf21c07a9e295d5b8a2a5ce678b913b45fdf68c32d95d6c1291e0b6"},
|
||||
{file = "MarkupSafe-3.0.2-cp313-cp313t-win_amd64.whl", hash = "sha256:e444a31f8db13eb18ada366ab3cf45fd4b31e4db1236a4448f68778c1d1a5a2f"},
|
||||
{file = "MarkupSafe-3.0.2-cp39-cp39-macosx_10_9_universal2.whl", hash = "sha256:eaa0a10b7f72326f1372a713e73c3f739b524b3af41feb43e4921cb529f5929a"},
|
||||
{file = "MarkupSafe-3.0.2-cp39-cp39-macosx_11_0_arm64.whl", hash = "sha256:48032821bbdf20f5799ff537c7ac3d1fba0ba032cfc06194faffa8cda8b560ff"},
|
||||
{file = "MarkupSafe-3.0.2-cp39-cp39-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:1a9d3f5f0901fdec14d8d2f66ef7d035f2157240a433441719ac9a3fba440b13"},
|
||||
{file = "MarkupSafe-3.0.2-cp39-cp39-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:88b49a3b9ff31e19998750c38e030fc7bb937398b1f78cfa599aaef92d693144"},
|
||||
{file = "MarkupSafe-3.0.2-cp39-cp39-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:cfad01eed2c2e0c01fd0ecd2ef42c492f7f93902e39a42fc9ee1692961443a29"},
|
||||
{file = "MarkupSafe-3.0.2-cp39-cp39-musllinux_1_2_aarch64.whl", hash = "sha256:1225beacc926f536dc82e45f8a4d68502949dc67eea90eab715dea3a21c1b5f0"},
|
||||
{file = "MarkupSafe-3.0.2-cp39-cp39-musllinux_1_2_i686.whl", hash = "sha256:3169b1eefae027567d1ce6ee7cae382c57fe26e82775f460f0b2778beaad66c0"},
|
||||
{file = "MarkupSafe-3.0.2-cp39-cp39-musllinux_1_2_x86_64.whl", hash = "sha256:eb7972a85c54febfb25b5c4b4f3af4dcc731994c7da0d8a0b4a6eb0640e1d178"},
|
||||
{file = "MarkupSafe-3.0.2-cp39-cp39-win32.whl", hash = "sha256:8c4e8c3ce11e1f92f6536ff07154f9d49677ebaaafc32db9db4620bc11ed480f"},
|
||||
{file = "MarkupSafe-3.0.2-cp39-cp39-win_amd64.whl", hash = "sha256:6e296a513ca3d94054c2c881cc913116e90fd030ad1c656b3869762b754f5f8a"},
|
||||
{file = "markupsafe-3.0.2.tar.gz", hash = "sha256:ee55d3edf80167e48ea11a923c7386f4669df67d7994554387f84e7d8b0a2bf0"},
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "packaging"
|
||||
version = "24.2"
|
||||
description = "Core utilities for Python packages"
|
||||
optional = false
|
||||
python-versions = ">=3.8"
|
||||
files = [
|
||||
{file = "packaging-24.2-py3-none-any.whl", hash = "sha256:09abb1bccd265c01f4a3aa3f7a7db064b36514d2cba19a2f694fe6150451a759"},
|
||||
{file = "packaging-24.2.tar.gz", hash = "sha256:c228a6dc5e932d346bc5739379109d49e8853dd8223571c7c5b55260edc0b97f"},
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "werkzeug"
|
||||
version = "3.1.3"
|
||||
description = "The comprehensive WSGI web application library."
|
||||
optional = false
|
||||
python-versions = ">=3.9"
|
||||
files = [
|
||||
{file = "werkzeug-3.1.3-py3-none-any.whl", hash = "sha256:54b78bf3716d19a65be4fceccc0d1d7b89e608834989dfae50ea87564639213e"},
|
||||
{file = "werkzeug-3.1.3.tar.gz", hash = "sha256:60723ce945c19328679790e3282cc758aa4a6040e4bb330f53d30fa546d44746"},
|
||||
]
|
||||
|
||||
[package.dependencies]
|
||||
MarkupSafe = ">=2.1.1"
|
||||
|
||||
[package.extras]
|
||||
watchdog = ["watchdog (>=2.3)"]
|
||||
|
||||
[metadata]
|
||||
lock-version = "2.0"
|
||||
python-versions = "^3.12"
|
||||
content-hash = "586b9c67ea1e0facc248baa9dd3ad0739dfacc8f6916dcc12e084d64e068dee4"
|
16
docker/deployer_docker/webhook/pyproject.toml
Normal file
16
docker/deployer_docker/webhook/pyproject.toml
Normal file
@ -0,0 +1,16 @@
|
||||
[tool.poetry]
|
||||
name = "webhook"
|
||||
version = "0.1.0"
|
||||
description = ""
|
||||
authors = ["Guilhem Lavaux <guilhem.lavaux@iap.fr>"]
|
||||
readme = "README.md"
|
||||
|
||||
[tool.poetry.dependencies]
|
||||
python = "^3.12"
|
||||
flask = "^3.1.0"
|
||||
gunicorn = "^23.0.0"
|
||||
|
||||
|
||||
[build-system]
|
||||
requires = ["poetry-core"]
|
||||
build-backend = "poetry.core.masonry.api"
|
10
docker/deployer_docker/webhook/requirements.txt
Normal file
10
docker/deployer_docker/webhook/requirements.txt
Normal file
@ -0,0 +1,10 @@
|
||||
blinker==1.9.0 ; python_version >= "3.12" and python_version < "4.0"
|
||||
click==8.1.7 ; python_version >= "3.12" and python_version < "4.0"
|
||||
colorama==0.4.6 ; python_version >= "3.12" and python_version < "4.0" and platform_system == "Windows"
|
||||
flask==3.1.0 ; python_version >= "3.12" and python_version < "4.0"
|
||||
gunicorn==23.0.0 ; python_version >= "3.12" and python_version < "4.0"
|
||||
itsdangerous==2.2.0 ; python_version >= "3.12" and python_version < "4.0"
|
||||
jinja2==3.1.4 ; python_version >= "3.12" and python_version < "4.0"
|
||||
markupsafe==3.0.2 ; python_version >= "3.12" and python_version < "4.0"
|
||||
packaging==24.2 ; python_version >= "3.12" and python_version < "4.0"
|
||||
werkzeug==3.1.3 ; python_version >= "3.12" and python_version < "4.0"
|
5
docker/deployer_docker/webhook/webhook.log
Normal file
5
docker/deployer_docker/webhook/webhook.log
Normal file
@ -0,0 +1,5 @@
|
||||
2024-11-19 07:53:50,765 - INFO - [31m[1mWARNING: This is a development server. Do not use it in a production deployment. Use a production WSGI server instead.[0m
|
||||
* Running on all addresses (0.0.0.0)
|
||||
* Running on http://127.0.0.1:5000
|
||||
* Running on http://192.168.2.116:5000
|
||||
2024-11-19 07:53:50,765 - INFO - [33mPress CTRL+C to quit[0m
|
Loading…
Reference in New Issue
Block a user