Compare commits
3
Commits
4ccd44937f
...
main
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
75b4cc92da | ||
|
|
f90c3b1424 | ||
|
|
12b28f037a |
@@ -0,0 +1,182 @@
|
|||||||
|
|
||||||
|
name: Build and Publish RMManager Image
|
||||||
|
|
||||||
|
on:
|
||||||
|
push:
|
||||||
|
branches: [main]
|
||||||
|
workflow_dispatch:
|
||||||
|
|
||||||
|
jobs:
|
||||||
|
build:
|
||||||
|
runs-on: ubuntu-latest
|
||||||
|
|
||||||
|
steps:
|
||||||
|
# ---------------------------------------------
|
||||||
|
# Checkout repository (no external actions)
|
||||||
|
# ---------------------------------------------
|
||||||
|
- name: Checkout repository
|
||||||
|
env:
|
||||||
|
GITEA_TOKEN: ${{ secrets.TEA_TOKEN }}
|
||||||
|
run: |
|
||||||
|
set -euo pipefail
|
||||||
|
|
||||||
|
BASE="${GITHUB_SERVER_URL%/}"
|
||||||
|
REPO="${GITHUB_REPOSITORY}"
|
||||||
|
|
||||||
|
git init .
|
||||||
|
git remote add origin "$BASE/$REPO.git"
|
||||||
|
|
||||||
|
if [ -n "${GITEA_TOKEN:-}" ]; then
|
||||||
|
AUTH="$(printf 'oauth2:%s' "$GITEA_TOKEN" | base64 -w0)"
|
||||||
|
git -c "http.extraHeader=Authorization: Basic $AUTH" \
|
||||||
|
fetch --depth 1 origin "$GITHUB_SHA"
|
||||||
|
else
|
||||||
|
git fetch --depth 1 origin "$GITHUB_SHA"
|
||||||
|
fi
|
||||||
|
|
||||||
|
git checkout --detach FETCH_HEAD
|
||||||
|
git config --global --add safe.directory "$PWD"
|
||||||
|
|
||||||
|
# ---------------------------------------------
|
||||||
|
# Determine image version and commit SHA
|
||||||
|
# ---------------------------------------------
|
||||||
|
- name: Determine version
|
||||||
|
id: version
|
||||||
|
run: |
|
||||||
|
set -euo pipefail
|
||||||
|
|
||||||
|
SHORT_SHA="$(git rev-parse --short=7 HEAD)"
|
||||||
|
echo "sha=$SHORT_SHA" >> "$GITHUB_OUTPUT"
|
||||||
|
|
||||||
|
if [ -f VERSION ]; then
|
||||||
|
VERSION="$(tr -d '[:space:]' < VERSION)"
|
||||||
|
echo "version=$VERSION" >> "$GITHUB_OUTPUT"
|
||||||
|
else
|
||||||
|
echo "version=" >> "$GITHUB_OUTPUT"
|
||||||
|
fi
|
||||||
|
|
||||||
|
# ---------------------------------------------
|
||||||
|
# Login to Gitea container registry
|
||||||
|
# ---------------------------------------------
|
||||||
|
- name: Docker login
|
||||||
|
env:
|
||||||
|
REGISTRY: ${{ vars.REGISTRY }}
|
||||||
|
REGISTRY_USER: ${{ secrets.REGISTRY_USER }}
|
||||||
|
REGISTRY_TOKEN: ${{ secrets.TEA_TOKEN }}
|
||||||
|
run: |
|
||||||
|
set -euo pipefail
|
||||||
|
|
||||||
|
echo "$REGISTRY_TOKEN" | docker login "$REGISTRY" \
|
||||||
|
-u "$REGISTRY_USER" \
|
||||||
|
--password-stdin
|
||||||
|
|
||||||
|
# ---------------------------------------------
|
||||||
|
# Build and export container image
|
||||||
|
# ---------------------------------------------
|
||||||
|
- name: Build RMManager image
|
||||||
|
env:
|
||||||
|
REGISTRY: ${{ vars.REGISTRY }}
|
||||||
|
VERSION: ${{ steps.version.outputs.version }}
|
||||||
|
SHORT_SHA: ${{ steps.version.outputs.sha }}
|
||||||
|
run: |
|
||||||
|
set -euo pipefail
|
||||||
|
|
||||||
|
FULL_IMAGE="$REGISTRY/david/rmmanager"
|
||||||
|
|
||||||
|
docker build \
|
||||||
|
-f Containerfile \
|
||||||
|
-t "$FULL_IMAGE:latest" \
|
||||||
|
-t "$FULL_IMAGE:sha-$SHORT_SHA" \
|
||||||
|
--output "type=docker,dest=$RUNNER_TEMP/rmmanager-built.tar" \
|
||||||
|
.
|
||||||
|
|
||||||
|
# ---------------------------------------------
|
||||||
|
# Load exported image into Docker
|
||||||
|
# ---------------------------------------------
|
||||||
|
- name: Load RMManager image
|
||||||
|
run: |
|
||||||
|
set -euo pipefail
|
||||||
|
|
||||||
|
docker load \
|
||||||
|
--input "$RUNNER_TEMP/rmmanager-built.tar"
|
||||||
|
|
||||||
|
# ---------------------------------------------
|
||||||
|
# Add optional version tag
|
||||||
|
# ---------------------------------------------
|
||||||
|
- name: Tag RMManager image
|
||||||
|
env:
|
||||||
|
REGISTRY: ${{ vars.REGISTRY }}
|
||||||
|
VERSION: ${{ steps.version.outputs.version }}
|
||||||
|
run: |
|
||||||
|
set -euo pipefail
|
||||||
|
|
||||||
|
FULL_IMAGE="$REGISTRY/david/rmmanager"
|
||||||
|
|
||||||
|
if [ -n "$VERSION" ]; then
|
||||||
|
docker tag \
|
||||||
|
"$FULL_IMAGE:latest" \
|
||||||
|
"$FULL_IMAGE:v$VERSION"
|
||||||
|
fi
|
||||||
|
|
||||||
|
# ---------------------------------------------
|
||||||
|
# Verify local image and tags
|
||||||
|
# ---------------------------------------------
|
||||||
|
- name: Verify RMManager image
|
||||||
|
env:
|
||||||
|
REGISTRY: ${{ vars.REGISTRY }}
|
||||||
|
VERSION: ${{ steps.version.outputs.version }}
|
||||||
|
SHORT_SHA: ${{ steps.version.outputs.sha }}
|
||||||
|
run: |
|
||||||
|
set -euo pipefail
|
||||||
|
|
||||||
|
FULL_IMAGE="$REGISTRY/david/rmmanager"
|
||||||
|
|
||||||
|
docker version
|
||||||
|
docker image ls
|
||||||
|
|
||||||
|
docker image inspect "$FULL_IMAGE:latest"
|
||||||
|
docker image inspect "$FULL_IMAGE:sha-$SHORT_SHA"
|
||||||
|
|
||||||
|
if [ -n "$VERSION" ]; then
|
||||||
|
docker image inspect "$FULL_IMAGE:v$VERSION"
|
||||||
|
fi
|
||||||
|
|
||||||
|
# ---------------------------------------------
|
||||||
|
# Publish image to Gitea registry
|
||||||
|
# ---------------------------------------------
|
||||||
|
- name: Push RMManager image
|
||||||
|
env:
|
||||||
|
REGISTRY: ${{ vars.REGISTRY }}
|
||||||
|
VERSION: ${{ steps.version.outputs.version }}
|
||||||
|
SHORT_SHA: ${{ steps.version.outputs.sha }}
|
||||||
|
run: |
|
||||||
|
set -euo pipefail
|
||||||
|
|
||||||
|
FULL_IMAGE="$REGISTRY/david/rmmanager"
|
||||||
|
|
||||||
|
docker push "$FULL_IMAGE:latest"
|
||||||
|
docker push "$FULL_IMAGE:sha-$SHORT_SHA"
|
||||||
|
|
||||||
|
if [ -n "$VERSION" ]; then
|
||||||
|
docker push "$FULL_IMAGE:v$VERSION"
|
||||||
|
fi
|
||||||
|
|
||||||
|
# ---------------------------------------------
|
||||||
|
# Report successful build
|
||||||
|
# ---------------------------------------------
|
||||||
|
- name: Report build
|
||||||
|
env:
|
||||||
|
REGISTRY: ${{ vars.REGISTRY }}
|
||||||
|
VERSION: ${{ steps.version.outputs.version }}
|
||||||
|
SHORT_SHA: ${{ steps.version.outputs.sha }}
|
||||||
|
run: |
|
||||||
|
set -euo pipefail
|
||||||
|
|
||||||
|
echo "RMManager build and publish completed"
|
||||||
|
echo "Image: $REGISTRY/david/rmmanager"
|
||||||
|
echo "Latest tag: latest"
|
||||||
|
echo "Commit tag: sha-$SHORT_SHA"
|
||||||
|
|
||||||
|
if [ -n "$VERSION" ]; then
|
||||||
|
echo "Version tag: v$VERSION"
|
||||||
|
fi
|
||||||
@@ -6,6 +6,7 @@ from core.runtime.resolver import resolveItem
|
|||||||
|
|
||||||
|
|
||||||
def buildFirewall(listener, outputs):
|
def buildFirewall(listener, outputs):
|
||||||
|
if hasattr(listener, "filters"):
|
||||||
#firewall_log = os.environ.get("LOGS_FIREWALL", "false").lower() == "true"
|
#firewall_log = os.environ.get("LOGS_FIREWALL", "false").lower() == "true"
|
||||||
firewall_log = True
|
firewall_log = True
|
||||||
|
|
||||||
|
|||||||
@@ -4,34 +4,48 @@ import logging
|
|||||||
from core.runtime.outputs import buildOutput
|
from core.runtime.outputs import buildOutput
|
||||||
from core.runtime.firewall import buildFirewall
|
from core.runtime.firewall import buildFirewall
|
||||||
from core.runtime.createruntime import outputs
|
from core.runtime.createruntime import outputs
|
||||||
|
from core.execution.processregistry import processes
|
||||||
|
|
||||||
|
|
||||||
def buildListener(listener, self):
|
def buildListener(listener, self):
|
||||||
if self.path.startswith(listener.acceptpath):
|
if self.path.startswith(listener.acceptpath):
|
||||||
|
if hasattr(listener, "print"):
|
||||||
#Prints can used buildlog for listener runtime
|
logging.info(listener.print)
|
||||||
logging.info("Matrix transaction received")
|
|
||||||
|
|
||||||
content_length = int(self.headers["Content-Length"])
|
content_length = int(self.headers["Content-Length"])
|
||||||
|
|
||||||
data = self.rfile.read(content_length)
|
bytes = self.rfile.read(content_length)
|
||||||
request = json.loads(data)
|
|
||||||
|
|
||||||
#outputs = {}
|
#request = json.loads(data)
|
||||||
|
|
||||||
buildOutput(data, listener, outputs)
|
buildOutput(bytes, listener, outputs)
|
||||||
|
|
||||||
|
if hasattr(listener, "filters"):
|
||||||
allow, status_code = buildFirewall(listener, outputs)
|
allow, status_code = buildFirewall(listener, outputs)
|
||||||
|
|
||||||
if allow:
|
if allow:
|
||||||
#from core.execution.createthread import buildThread
|
|
||||||
from core.execution.executioncontract import executeContract
|
|
||||||
|
|
||||||
logging.info(outputs["firewall_allowed"])
|
logging.info(outputs["firewall_allowed"])
|
||||||
|
|
||||||
#thread = buildThread(listener.execute)
|
if hasattr(listener, "execute"):
|
||||||
executeContract(listener.execute)
|
if listener.execute["engine"] == "thread":
|
||||||
|
from core.execution.createthread import buildThread
|
||||||
|
buildThread(listener.execute["module"])
|
||||||
|
|
||||||
|
elif listener.execute["engine"] == "contract":
|
||||||
|
from core.execution.executioncontract import executeContract
|
||||||
|
executeContract(listener.execute["module"])
|
||||||
|
|
||||||
|
else:
|
||||||
|
if hasattr(listener, "execute"):
|
||||||
|
if listener.execute["engine"] == "thread":
|
||||||
|
from core.execution.createthread import buildThread
|
||||||
|
buildThread(listener.execute["module"])
|
||||||
|
|
||||||
|
elif listener.execute["engine"] == "contract":
|
||||||
|
from core.execution.executioncontract import executeContract
|
||||||
|
executeContract(listener.execute["module"])
|
||||||
|
|
||||||
|
status_code = listener.status_code["success"]
|
||||||
|
|
||||||
self.send_response(status_code)
|
self.send_response(status_code)
|
||||||
self.send_header("Content-Type", "application/json")
|
self.send_header("Content-Type", "application/json")
|
||||||
@@ -42,4 +56,4 @@ def buildListener(listener, self):
|
|||||||
else:
|
else:
|
||||||
self.send_error(404)
|
self.send_error(404)
|
||||||
|
|
||||||
return outputs
|
return
|
||||||
+82
-80
@@ -4,119 +4,121 @@ import logging
|
|||||||
|
|
||||||
from http.server import HTTPServer, BaseHTTPRequestHandler
|
from http.server import HTTPServer, BaseHTTPRequestHandler
|
||||||
|
|
||||||
from .dispatcher import dispatchRequest
|
|
||||||
from .createresponse import buildResponse
|
#from .dispatcher import dispatchRequest
|
||||||
from plugins.rmass.listeners import synapselistener
|
#from .createresponse import buildResponse
|
||||||
|
from plugins.rmass.listeners import synapselistener, matrixpinglistener
|
||||||
from core.server.createlistener import buildListener
|
from core.server.createlistener import buildListener
|
||||||
from plugins.rmass.actions import synapsesetbridgeonline
|
#from plugins.rmass.actions import synapsesetbridgeonline
|
||||||
|
|
||||||
port = int(os.environ.get("SERVER_PORT", 19001))
|
port = int(os.environ.get("SERVER_PORT", 19001))
|
||||||
|
|
||||||
|
|
||||||
class RequestHandler(BaseHTTPRequestHandler):
|
class RequestHandler(BaseHTTPRequestHandler):
|
||||||
def do_POST(self):
|
def do_POST(self):
|
||||||
if self.path == "/_matrix/app/v1/ping":
|
logging.debug("POST request received")
|
||||||
|
|
||||||
from core.execution.createthread import buildThread
|
buildListener(matrixpinglistener, self)
|
||||||
thread = buildThread(synapsesetbridgeonline)
|
|
||||||
|
|
||||||
self.send_response(200)
|
# if self.path == "/_matrix/app/v1/ping":
|
||||||
self.send_header("Content-Type", "application/json")
|
|
||||||
self.send_header("Content-Length", "2")
|
|
||||||
self.end_headers()
|
|
||||||
self.wfile.write(b"{}")
|
|
||||||
return
|
|
||||||
|
|
||||||
else:
|
# from core.execution.createthread import buildThread
|
||||||
#lifecycles = {}
|
# thread = buildThread(synapsesetbridgeonline)
|
||||||
print("POST request received")
|
|
||||||
|
|
||||||
max_request_size = 1024
|
# self.send_response(200)
|
||||||
|
# self.send_header("Content-Type", "application/json")
|
||||||
|
# self.send_header("Content-Length", "2")
|
||||||
|
# self.end_headers()
|
||||||
|
# self.wfile.write(b"{}")
|
||||||
|
# return
|
||||||
|
|
||||||
content_length = self.headers.get("Content-Length")
|
# else:
|
||||||
|
# print("POST request received")
|
||||||
|
|
||||||
# Check whether Content-Length exists
|
# max_request_size = 1024
|
||||||
if content_length is None:
|
|
||||||
response = {
|
|
||||||
"status": "error",
|
|
||||||
"message": "Content length required"
|
|
||||||
}
|
|
||||||
status = 411
|
|
||||||
|
|
||||||
else:
|
# content_length = self.headers.get("Content-Length")
|
||||||
# Attempt to convert the header into an integer
|
|
||||||
try:
|
|
||||||
length = int(content_length)
|
|
||||||
except ValueError:
|
|
||||||
length = None
|
|
||||||
|
|
||||||
# Validate the converted length
|
# # Check whether Content-Length exists
|
||||||
if length is None:
|
# if content_length is None:
|
||||||
response = {
|
# response = {
|
||||||
"status": "error",
|
# "status": "error",
|
||||||
"message": "Invalid Content-Length"
|
# "message": "Content length required"
|
||||||
}
|
# }
|
||||||
status = 400
|
# status = 411
|
||||||
|
|
||||||
elif length < 0:
|
# else:
|
||||||
response = {
|
# # Attempt to convert the header into an integer
|
||||||
"status": "error",
|
# try:
|
||||||
"message": "Bad Request"
|
# length = int(content_length)
|
||||||
}
|
# except ValueError:
|
||||||
status = 400
|
# length = None
|
||||||
|
|
||||||
elif length > max_request_size:
|
# # Validate the converted length
|
||||||
response = {
|
# if length is None:
|
||||||
"status": "error",
|
# response = {
|
||||||
"message": "Content exceeds maximum request size"
|
# "status": "error",
|
||||||
}
|
# "message": "Invalid Content-Length"
|
||||||
status = 413
|
# }
|
||||||
|
# status = 400
|
||||||
|
|
||||||
else:
|
# elif length < 0:
|
||||||
# Content-Length is valid, so read the body
|
# response = {
|
||||||
data = self.rfile.read(length)
|
# "status": "error",
|
||||||
|
# "message": "Bad Request"
|
||||||
|
# }
|
||||||
|
# status = 400
|
||||||
|
|
||||||
try:
|
# elif length > max_request_size:
|
||||||
request = json.loads(data)
|
# response = {
|
||||||
|
# "status": "error",
|
||||||
|
# "message": "Content exceeds maximum request size"
|
||||||
|
# }
|
||||||
|
# status = 413
|
||||||
|
|
||||||
except json.JSONDecodeError:
|
# else:
|
||||||
response = {
|
# # Content-Length is valid, so read the body
|
||||||
"status": "error",
|
# data = self.rfile.read(length)
|
||||||
"message": "Invalid JSON received"
|
|
||||||
}
|
|
||||||
status = 400
|
|
||||||
|
|
||||||
else:
|
# try:
|
||||||
# Only valid JSON reaches the dispatcher
|
# request = json.loads(data)
|
||||||
thread, lifecycles, module, mode = dispatchRequest(
|
|
||||||
request, lifecycles
|
|
||||||
)
|
|
||||||
|
|
||||||
response = buildResponse(module, thread, mode)
|
# except json.JSONDecodeError:
|
||||||
status = 200
|
# response = {
|
||||||
|
# "status": "error",
|
||||||
|
# "message": "Invalid JSON received"
|
||||||
|
# }
|
||||||
|
# status = 400
|
||||||
|
|
||||||
# Serialize the response
|
# else:
|
||||||
responsebytes = json.dumps(response).encode("utf-8")
|
# # Only valid JSON reaches the dispatcher
|
||||||
|
# thread, lifecycles, module, mode = dispatchRequest(
|
||||||
|
# request, lifecycles
|
||||||
|
# )
|
||||||
|
|
||||||
# Send one HTTP response
|
# response = buildResponse(module, thread, mode)
|
||||||
self.send_response(status)
|
# status = 200
|
||||||
self.send_header("Content-Type", "application/json")
|
|
||||||
self.send_header("Content-Length", str(len(responsebytes)))
|
|
||||||
self.end_headers()
|
|
||||||
|
|
||||||
self.wfile.write(responsebytes)
|
# # Serialize the response
|
||||||
|
# responsebytes = json.dumps(response).encode("utf-8")
|
||||||
|
|
||||||
|
# # Send one HTTP response
|
||||||
|
# self.send_response(status)
|
||||||
|
# self.send_header("Content-Type", "application/json")
|
||||||
|
# self.send_header("Content-Length", str(len(responsebytes)))
|
||||||
|
# self.end_headers()
|
||||||
|
|
||||||
|
# self.wfile.write(responsebytes)
|
||||||
|
|
||||||
|
|
||||||
def do_PUT(self):
|
def do_PUT(self):
|
||||||
#print("PUT request received")
|
logging.debug("PUT request received")
|
||||||
|
|
||||||
outputs = buildListener(synapselistener, self)
|
buildListener(synapselistener, self)
|
||||||
|
|
||||||
def startServer():
|
def startServer():
|
||||||
server = HTTPServer(("0.0.0.0", port), RequestHandler)
|
server = HTTPServer(("0.0.0.0", port), RequestHandler)
|
||||||
|
|
||||||
logging.info(f"Server listening on port {port}")
|
logging.info(f"Server listening on port {port}")
|
||||||
#outputs = {}
|
|
||||||
#outputs, response = buildAction(pingsynapse, outputs)
|
|
||||||
|
|
||||||
server.serve_forever()
|
server.serve_forever()
|
||||||
@@ -0,0 +1,16 @@
|
|||||||
|
from plugins.rmass.actions import synapsesetbridgeonline
|
||||||
|
|
||||||
|
name = "Matrix Ping Listener"
|
||||||
|
|
||||||
|
kind = "listener"
|
||||||
|
|
||||||
|
acceptpath = "/_matrix/app/v1/ping"
|
||||||
|
|
||||||
|
execute = {
|
||||||
|
"module": synapsesetbridgeonline,
|
||||||
|
"engine": "thread",
|
||||||
|
}
|
||||||
|
|
||||||
|
status_code = {
|
||||||
|
"success": 200
|
||||||
|
}
|
||||||
@@ -30,7 +30,10 @@ recursive = {
|
|||||||
|
|
||||||
acceptpath = "/_matrix/app/v1/transactions/"
|
acceptpath = "/_matrix/app/v1/transactions/"
|
||||||
|
|
||||||
execute = rmassmessagepush
|
execute = {
|
||||||
|
"module": rmassmessagepush,
|
||||||
|
"engine": "contract",
|
||||||
|
}
|
||||||
|
|
||||||
filters = [
|
filters = [
|
||||||
{
|
{
|
||||||
@@ -74,3 +77,4 @@ filters = [
|
|||||||
|
|
||||||
]
|
]
|
||||||
|
|
||||||
|
print = "Matrix transaction received"
|
||||||
Reference in New Issue
Block a user