diff --git a/server/Dockerfile b/server/Dockerfile new file mode 100644 index 0000000..6650741 --- /dev/null +++ b/server/Dockerfile @@ -0,0 +1,22 @@ +FROM python:3.8 as build + +WORKDIR /home/recceiver + +COPY . ./server + +RUN python -m venv venv && \ + venv/bin/pip install \ + --no-cache-dir \ + -i https://artifactory.esss.lu.se/artifactory/api/pypi/pypi-virtual/simple \ + -r server/requirements.txt + +RUN venv/bin/python -m pip install ./server + +FROM python:3.8-slim + +WORKDIR /home/recceiver + +COPY --from=build /home/recceiver/venv venv + +CMD venv/bin/twistd --pidfile= --nodaemon recceiver --config cf.conf + diff --git a/server/README b/server/README.md similarity index 95% rename from server/README rename to server/README.md index 0441033..d2adaa8 100644 --- a/server/README +++ b/server/README.md @@ -1,4 +1,6 @@ -Server testing +# Recceiver + +## Server testing Setup diff --git a/server/cf1.conf b/server/cf1.conf new file mode 100644 index 0000000..b552ae7 --- /dev/null +++ b/server/cf1.conf @@ -0,0 +1,60 @@ +# run with +#twistd -n recceiver -f .conf + +[recceiver] + +# list of broadcast addresses. +# default +#addrlist = 255.255.255.255:5049 +# for local testing w/ firewall +#addrlist = 127.255.255.255:5049 + +# Listen for TCP connections on this interface and port. +# Port also used as source for UDP broadcasts. +# Default uses wildcard address and a random port. +#bind = 0.0.0.0:0 + +# Processing chain +procs = cf + +# Time interval for sending recceiver advertisments +#announceInterval = 15.0 + +# Idle Timeout for TCP connections. +#tcptimeout = 15.0 + +# Time to wait before commiting updates +# Doesn't effect IOC clients +#commitInterval = 5.0 + +# Maximum concurrent "active" clients +# to allow. +#maxActive = 20 + +# The channelFinder client is configuration information is +# stored in /etc/channelfinderapi.conf as described in the client + +[cf] +# a space-separated list of infotags to set as CF Properties +#infotags = archive foo bar blah +# List environment variables that should be written as channel finder properties +# +# Comma-separated list of VARIABLE:PropertyName, +# specifying which environment VARIABLEs to pass on to the channel finder +# and defining the corresponding PropertyName +#environment_vars=ENGINEER:Engineer,EPICS_BASE:EpicsVersion,PWD:WorkingDirectory +# Turn on optional alias and recordType properties +#alias = on +#recordType = on +#recordDesc = on + +# Mark all channels as 'Inactive' when processor is stopped (default: True) +cleanOnStop = True +# Mark all channels as 'Inactive' when processor is started (default: True) +#cleanOnStart = True + +recceiverID = recc1 +[DEFAULT] +BaseURL = http://cf:8080/ChannelFinder +username = admin +password = password diff --git a/server/cf2.conf b/server/cf2.conf new file mode 100644 index 0000000..328a1b7 --- /dev/null +++ b/server/cf2.conf @@ -0,0 +1,61 @@ +# run with +#twistd -n recceiver -f .conf + +[recceiver] + +# list of broadcast addresses. +# default +#addrlist = 255.255.255.255:5049 +# for local testing w/ firewall +#addrlist = 127.255.255.255:5049 + +# Listen for TCP connections on this interface and port. +# Port also used as source for UDP broadcasts. +# Default uses wildcard address and a random port. +#bind = 0.0.0.0:0 + +# Processing chain +procs = cf + +# Time interval for sending recceiver advertisments +#announceInterval = 15.0 + +# Idle Timeout for TCP connections. +#tcptimeout = 15.0 + +# Time to wait before commiting updates +# Doesn't effect IOC clients +#commitInterval = 5.0 + +# Maximum concurrent "active" clients +# to allow. +#maxActive = 20 + +# The channelFinder client is configuration information is +# stored in /etc/channelfinderapi.conf as described in the client + +[cf] +# a space-separated list of infotags to set as CF Properties +#infotags = archive foo bar blah +# List environment variables that should be written as channel finder properties +# +# Comma-separated list of VARIABLE:PropertyName, +# specifying which environment VARIABLEs to pass on to the channel finder +# and defining the corresponding PropertyName +#environment_vars=ENGINEER:Engineer,EPICS_BASE:EpicsVersion,PWD:WorkingDirectory +# Turn on optional alias and recordType properties +#alias = on +#recordType = on +#recordDesc = on + +# Mark all channels as 'Inactive' when processor is stopped (default: True) +#cleanOnStop = True +# Mark all channels as 'Inactive' when processor is started (default: True) +cleanOnStart = True + +recceiverID = recc2 + +[DEFAULT] +BaseURL = http://cf:8080/ChannelFinder +username = admin +password = password diff --git a/server/docker-compose.yml b/server/docker-compose.yml new file mode 100644 index 0000000..5211bf5 --- /dev/null +++ b/server/docker-compose.yml @@ -0,0 +1,95 @@ +version: '3' + +services: + cf: + image: ghcr.io/channelfinder/channelfinderservice:master + hostname: cf + networks: + - net-cf + ports: + - "8080:8080" + - "8443:8443" + depends_on: + elasticsearch: + condition: service_healthy + restart: true + environment: + ELASTICSEARCH_NETWORK_HOST: elasticsearch-cf + elasticsearch.query.size: 10 + demo_auth.enabled: true + demo_auth.users: admin + demo_auth.pwds: password + demo_auth.roles: ADMIN + EPICS_PVAS_INTF_ADDR_LIST: "0.0.0.0" + healthcheck: + test: curl -s -f http://cf:8080/ChannelFinder + interval: 10s + timeout: 60s + retries: 5 + + elasticsearch: + image: docker.elastic.co/elasticsearch/elasticsearch:8.11.4 + hostname: elasticsearch-cf + networks: + - net-cf + environment: + cluster.name: channelfinder + discovery.type: single-node + bootstrap.memory_lock: "true" + xpack.security.enabled: "false" + healthcheck: + test: curl -s -f http://localhost:9200/_cluster/health + interval: 10s + timeout: 60s + retries: 5 + volumes: + - channelfinder-es-data:/usr/share/elasticsearch/data + + recc1: + build: . + networks: + - net-recc-1 + - net-cf + depends_on: + cf: + condition: service_healthy + restart: true + volumes: + - type: bind + source: cf1.conf + target: /home/recceiver/cf.conf + read_only: true + - type: bind + source: cf1.conf + target: /home/recceiver/channelfinderapi.conf + read_only: true + recc2: + build: . + networks: + - net-recc-2 + - net-cf + depends_on: + cf: + condition: service_healthy + restart: true + volumes: + - type: bind + source: cf2.conf + target: /home/recceiver/cf.conf + read_only: true + - type: bind + source: cf2.conf + target: /home/recceiver/channelfinderapi.conf + read_only: true + +volumes: + channelfinder-es-data: + driver: local + +networks: + net-cf: + driver: bridge + net-recc-1: + driver: bridge + net-recc-2: + driver: bridge \ No newline at end of file diff --git a/server/pyproject.toml b/server/pyproject.toml index 9143b16..b7abcea 100644 --- a/server/pyproject.toml +++ b/server/pyproject.toml @@ -1,5 +1,5 @@ [build-system] -requires = ["setuptools", "setuptools-scm"] +requires = ["setuptools"] build-backend = "setuptools.build_meta" [project] @@ -9,11 +9,12 @@ authors = [ ] description="resync server" version="1.5" -readme = "README.rst" +readme = "README.md" requires-python = ">=3.6" dependencies = [ -# "requests", - "twisted", + "twisted", + "requests", + "channelfinder" ] [project.urls] @@ -24,4 +25,4 @@ packages = ["recceiver", "twisted.plugins"] include-package-data = true [tool.setuptools.package-data] -twisted = ["plugins/recceiver_plugin.py"] +twisted = ["plugins/recceiver_plugin.py"] \ No newline at end of file diff --git a/server/recceiver/application.py b/server/recceiver/application.py index 50da82b..257d901 100644 --- a/server/recceiver/application.py +++ b/server/recceiver/application.py @@ -6,6 +6,9 @@ from zope.interface import implementer from twisted import plugin +from twisted.internet import pollreactor +pollreactor.install() + from twisted.python import usage, log from twisted.internet import reactor, defer from twisted.internet.error import CannotListenError diff --git a/server/requirements.txt b/server/requirements.txt new file mode 100644 index 0000000..6616644 --- /dev/null +++ b/server/requirements.txt @@ -0,0 +1,3 @@ +channelfinder==3.0.0.post2 +twisted==22.8.0 +requests==2.28.1 diff --git a/server/setup.py b/server/setup.py deleted file mode 100644 index beda28e..0000000 --- a/server/setup.py +++ /dev/null @@ -1,5 +0,0 @@ -#!/usr/bin/env python - -from setuptools import setup - -setup() diff --git a/server/test.py b/server/test.py new file mode 100644 index 0000000..b4749fa --- /dev/null +++ b/server/test.py @@ -0,0 +1,35 @@ +import json + +import urllib3 + +def insert_fake_data(recc:str, cf: str, ch: str): + http = urllib3.PoolManager() + headers = urllib3.make_headers(basic_auth='admin:password') + headers.update({'Content-Type': + 'application/json'}) + req = http.request('PUT', cf +"/ChannelFinder/resources/channels", + headers=headers, + body=json.dumps([ + { + "name": ch, + "owner": recc, + "properties": [ + { + "name": "recceiverID", + "owner": recc, + "value": recc + }, + { + "name":"pvStatus", + "owner": recc, + "value": "Active" + } + ] + } + ])) + + +cf = "http://localhost:8080" +for i in range(1, 20): + insert_fake_data("recc1", cf, "ch" + str(i)) + insert_fake_data("recc2", cf, "ch" + str(i))