Compare commits

..
4 Commits
Author SHA1 Message Date
Lyncoln 9e937d7686 Changed log level of self.address_string
Build and Publish RMManager Image / build (push) Successful in 56s
2026-10-31 09:11:39 -04:00
Lyncoln 75b4cc92da Repaired build workflow
Build and Publish RMManager Image / build (push) Successful in 46s
2026-10-30 23:41:42 -04:00
Lyncoln f90c3b1424 Added gitea workflow build
Build and Publish RMManager Image / build (push) Failing after 1m31s
2026-10-30 23:37:45 -04:00
Lyncoln 12b28f037a Updated Server to used buildListener for pings and updated the listener and firewall to handle definitions accordingly 2026-10-30 22:50:36 -04:00
6 changed files with 346 additions and 120 deletions
+182
View File
@@ -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
+1
View File
@@ -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
+27 -13
View File
@@ -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
+103 -94
View File
@@ -4,119 +4,128 @@ 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 log_message(self, format, *args):
if self.path == "/_matrix/app/v1/ping": logging.info(
"%s - %s",
from core.execution.createthread import buildThread self.address_string(),
thread = buildThread(synapsesetbridgeonline) format % args
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
else:
#lifecycles = {}
print("POST request received")
max_request_size = 1024
content_length = self.headers.get("Content-Length")
# Check whether Content-Length exists
if content_length is None:
response = {
"status": "error",
"message": "Content length required"
}
status = 411
else:
# Attempt to convert the header into an integer
try:
length = int(content_length)
except ValueError:
length = None
# Validate the converted length
if length is None:
response = {
"status": "error",
"message": "Invalid Content-Length"
}
status = 400
elif length < 0:
response = {
"status": "error",
"message": "Bad Request"
}
status = 400
elif length > max_request_size:
response = {
"status": "error",
"message": "Content exceeds maximum request size"
}
status = 413
else:
# Content-Length is valid, so read the body
data = self.rfile.read(length)
try:
request = json.loads(data)
except json.JSONDecodeError:
response = {
"status": "error",
"message": "Invalid JSON received"
}
status = 400
else:
# Only valid JSON reaches the dispatcher
thread, lifecycles, module, mode = dispatchRequest(
request, lifecycles
) )
response = buildResponse(module, thread, mode) def do_POST(self):
status = 200 logging.debug("POST request received")
# Serialize the response buildListener(matrixpinglistener, self)
responsebytes = json.dumps(response).encode("utf-8")
# Send one HTTP response # if self.path == "/_matrix/app/v1/ping":
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) # from core.execution.createthread import buildThread
# thread = buildThread(synapsesetbridgeonline)
# 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
# else:
# print("POST request received")
# max_request_size = 1024
# content_length = self.headers.get("Content-Length")
# # Check whether Content-Length exists
# if content_length is None:
# response = {
# "status": "error",
# "message": "Content length required"
# }
# status = 411
# else:
# # Attempt to convert the header into an integer
# try:
# length = int(content_length)
# except ValueError:
# length = None
# # Validate the converted length
# if length is None:
# response = {
# "status": "error",
# "message": "Invalid Content-Length"
# }
# status = 400
# elif length < 0:
# response = {
# "status": "error",
# "message": "Bad Request"
# }
# status = 400
# elif length > max_request_size:
# response = {
# "status": "error",
# "message": "Content exceeds maximum request size"
# }
# status = 413
# else:
# # Content-Length is valid, so read the body
# data = self.rfile.read(length)
# try:
# request = json.loads(data)
# except json.JSONDecodeError:
# response = {
# "status": "error",
# "message": "Invalid JSON received"
# }
# status = 400
# else:
# # Only valid JSON reaches the dispatcher
# thread, lifecycles, module, mode = dispatchRequest(
# request, lifecycles
# )
# response = buildResponse(module, thread, mode)
# status = 200
# # 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
}
+5 -1
View File
@@ -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"