1
0
mirror of https://github.com/craigerl/aprsd.git synced 2026-08-16 16:43:52 -04:00

Compare commits

..

13 Commits

Author SHA1 Message Date
hemna 0527ddfdba Update Changelog to 3.0.3 2023-04-25 14:44:56 -04:00
hemna 5694cabd93 cleanup some debug messages 2023-04-25 14:29:26 -04:00
hemna e21e2a7c50 Fixed loading of plugins for server
Some instances the plugins failed to load
2023-04-20 14:31:50 -04:00
hemna 17d9c06b07 Don't load help plugin for listen command
This patch disables loading the help plugin for the listen command.
2023-04-17 15:37:48 -04:00
hemna 66ebb286d8 Added listen args. 2023-04-17 15:31:07 -04:00
hemna 0ec41f7605 Change listen command plugins
The listen command now adds the --load-plugins, which is false by
default, to load all the plugins as defined in the config file.
2023-04-17 15:01:57 -04:00
hemna c353877321 Added listen.sh for docker
This patch adds the listen.sh entry point for the docker image.
2023-04-17 15:45:49 +00:00
hemna 483afce5ad Update Listen command
This patch updates the aprsd listen command to add the packet-plugins
argument which allows enabling a single plugin to work against the
packets recieved from the aprsis network.
2023-04-17 10:51:17 -04:00
hemna 8a456cac48 Update Dockerfile 2023-01-31 17:36:39 +00:00
hemna 62e1d69272 Merge pull request #111 from craigerl/ratelimit
Add ratelimiting for acks and other packets
2023-01-18 14:01:41 -05:00
hemna 840b0aba97 Add ratelimiting for acks and other packets
This patch adds basic ratelimiting to sending out AckPackets
and non AckPackets.  This provides a basic way to prevent
aprsd from sending out packets as fast as possible, which isn't
great for a bandwidth limited network.

This patch also adds some keepalive checks to all threads in the
threadslist as well as the network client objects (apris, kiss)
2023-01-18 13:00:10 -05:00
hemna 357a193a75 Update Changelog for 3.0.2 2023-01-16 11:41:42 -05:00
hemna 4aa4a4b5d3 Import RejectPacket 2023-01-16 11:38:48 -05:00
24 changed files with 274 additions and 81 deletions
+20
View File
@@ -1,9 +1,29 @@
CHANGES
=======
v3.0.3
------
* cleanup some debug messages
* Fixed loading of plugins for server
* Don't load help plugin for listen command
* Added listen args
* Change listen command plugins
* Added listen.sh for docker
* Update Listen command
* Update Dockerfile
* Add ratelimiting for acks and other packets
v3.0.2
------
* Update Changelog for 3.0.2
* Import RejectPacket
v3.0.1
------
* 3.0.1
* Add support to Reject messages
* Update Docker builds for 3.0.0
+18 -3
View File
@@ -84,6 +84,8 @@ class Client:
class APRSISClient(Client):
_client = None
@staticmethod
def is_enabled():
# Defaults to True if the enabled flag is non existent
@@ -115,6 +117,12 @@ class APRSISClient(Client):
return True
return True
def is_alive(self):
if self._client:
return self._client.is_alive()
else:
return False
@staticmethod
def transport():
return TRANSPORT_APRSIS
@@ -157,6 +165,8 @@ class APRSISClient(Client):
class KISSClient(Client):
_client = None
@staticmethod
def is_enabled():
"""Return if tcp or serial KISS is enabled."""
@@ -189,6 +199,12 @@ class KISSClient(Client):
return True
return False
def is_alive(self):
if self._client:
return self._client.is_alive()
else:
return False
@staticmethod
def transport():
if CONF.kiss_serial.enabled:
@@ -214,8 +230,8 @@ class KISSClient(Client):
@trace.trace
def setup_connection(self):
client = kiss.KISS3Client()
return client
self._client = kiss.KISS3Client()
return self._client
class ClientFactory:
@@ -241,7 +257,6 @@ class ClientFactory:
elif KISSClient.is_enabled():
key = KISSClient.transport()
LOG.debug(f"GET client '{key}'")
builder = self._builders.get(key)
if not builder:
raise ValueError(key)
+4
View File
@@ -37,6 +37,10 @@ class Aprsdis(aprslib.IS):
"""Send an APRS Message object."""
self.sendall(packet.raw)
def is_alive(self):
"""If the connection is alive or not."""
return self._connected
def _socket_readlines(self, blocking=False):
"""
Generator for complete lines, received from the server
+3
View File
@@ -17,6 +17,9 @@ class KISS3Client:
def __init__(self):
self.setup()
def is_alive(self):
return True
def setup(self):
# we can be TCP kiss or Serial kiss
if CONF.kiss_serial.enabled:
+1 -3
View File
@@ -101,8 +101,6 @@ def test_plugin(
pm = plugin.PluginManager()
if load_all:
pm.setup_plugins()
else:
pm._init()
obj = pm._create_class(plugin_path, plugin.APRSDPluginBase)
if not obj:
click.echo(ctx.get_help())
@@ -116,7 +114,7 @@ def test_plugin(
obj.__class__, obj.version,
),
)
pm._pluggy_pm.register(obj)
pm.register_msg(obj)
packet = packets.MessagePacket(
from_call=fromcall,
+34 -3
View File
@@ -15,7 +15,7 @@ from rich.console import Console
# local imports here
import aprsd
from aprsd import cli_helper, client, packets, stats, threads
from aprsd import cli_helper, client, packets, plugin, stats, threads
from aprsd.aprsd import cli
from aprsd.threads import rx
@@ -40,9 +40,12 @@ def signal_handler(sig, frame):
class APRSDListenThread(rx.APRSDRXThread):
def __init__(self, packet_queue, packet_filter=None):
def __init__(self, packet_queue, packet_filter=None, plugin_manager=None):
super().__init__(packet_queue)
self.packet_filter = packet_filter
self.plugin_manager = plugin_manager
if self.plugin_manager:
LOG.info(f"Plugins {self.plugin_manager.get_message_plugins()}")
def process_packet(self, *args, **kwargs):
packet = self._client.decode_packet(*args, **kwargs)
@@ -59,8 +62,17 @@ class APRSDListenThread(rx.APRSDRXThread):
filter_class = filters[self.packet_filter]
if isinstance(packet, filter_class):
packet.log(header="RX")
if self.plugin_manager:
# Don't do anything with the reply
# This is the listen only command.
self.plugin_manager.run(packet)
else:
packet.log(header="RX")
if self.plugin_manager:
# Don't do anything with the reply.
# This is the listen only command.
self.plugin_manager.run(packet)
else:
packet.log(header="RX")
packets.PacketList().rx(packet)
@@ -94,6 +106,12 @@ class APRSDListenThread(rx.APRSDRXThread):
),
help="Filter by packet type",
)
@click.option(
"--load-plugins",
default=False,
is_flag=True,
help="Load plugins as enabled in aprsd.conf ?",
)
@click.argument(
"filter",
nargs=-1,
@@ -106,6 +124,7 @@ def listen(
aprs_login,
aprs_password,
packet_filter,
load_plugins,
filter,
):
"""Listen to packets on the APRS-IS Network based on FILTER.
@@ -162,10 +181,22 @@ def listen(
keepalive = threads.KeepAliveThread()
keepalive.start()
pm = None
pm = plugin.PluginManager()
if load_plugins:
LOG.info("Loading plugins")
pm.setup_plugins(load_help_plugin=False)
else:
LOG.warning(
"Not Loading any plugins use --load-plugins to load what's "
"defined in the config file.",
)
LOG.debug("Create APRSDListenThread")
listen_thread = APRSDListenThread(
packet_queue=threads.packet_queue,
packet_filter=packet_filter,
plugin_manager=pm,
)
LOG.debug("Start APRSDListenThread")
listen_thread.start()
+8
View File
@@ -57,6 +57,14 @@ def server(ctx, flush):
# Dump all the config options now.
CONF.log_opt_values(LOG, logging.DEBUG)
message_plugins = plugin_manager.get_message_plugins()
watchlist_plugins = plugin_manager.get_watchlist_plugins()
LOG.info("Message Plugins enabled and running:")
for p in message_plugins:
LOG.info(p)
LOG.info("Watchlist Plugins enabled and running:")
for p in watchlist_plugins:
LOG.info(p)
# Make sure we have 1 client transport enabled
if not client.factory.is_client_enabled():
+14
View File
@@ -47,6 +47,20 @@ aprsd_opts = [
default="imperial",
help="Units for display, imperial or metric",
),
cfg.IntOpt(
"ack_rate_limit_period",
default=1,
help="The wait period in seconds per Ack packet being sent."
"1 means 1 ack packet per second allowed."
"2 means 1 pack packet every 2 seconds allowed",
),
cfg.IntOpt(
"msg_rate_limit_period",
default=2,
help="Wait period in seconds per non AckPacket being sent."
"2 means 1 packet every 2 seconds allowed."
"5 means 1 pack packet every 5 seconds allowed",
),
]
watch_list_opts = [
+1 -1
View File
@@ -1,6 +1,6 @@
from aprsd.packets.core import ( # noqa: F401
AckPacket, GPSPacket, MessagePacket, MicEPacket, Packet, PathPacket,
StatusPacket, WeatherPacket,
RejectPacket, StatusPacket, WeatherPacket,
)
from aprsd.packets.packet_list import PacketList # noqa: F401
from aprsd.packets.seen_list import SeenList # noqa: F401
+10
View File
@@ -183,6 +183,16 @@ class Packet(metaclass=abc.ABCMeta):
self.prepare()
return self.raw
def __repr__(self):
"""Build the repr version of the packet."""
repr = (
f"{self.__class__.__name__}:"
f" From: {self.from_call} "
" To: "
)
return repr
@dataclass
class PathPacket(Packet):
+23 -17
View File
@@ -207,13 +207,14 @@ class APRSDRegexCommandPluginBase(APRSDPluginBase, metaclass=abc.ABCMeta):
@hookimpl
def filter(self, packet: packets.core.MessagePacket):
LOG.info(f"{self.__class__.__name__} called")
if not self.enabled:
result = f"{self.__class__.__name__} isn't enabled"
LOG.warning(result)
return result
if not isinstance(packet, packets.core.MessagePacket):
LOG.warning(f"Got a {packet.__class__.__name__} ignoring")
LOG.warning(f"{self.__class__.__name__} Got a {packet.__class__.__name__} ignoring")
return packets.NULL_MESSAGE
result = None
@@ -324,9 +325,6 @@ class PluginManager:
# the pluggy PluginManager for all WatchList plugins
_watchlist_pm = None
# aprsd config dict
config = None
lock = None
def __new__(cls, *args, **kwargs):
@@ -335,13 +333,9 @@ class PluginManager:
cls._instance = super().__new__(cls)
# Put any initialization here.
cls._instance.lock = threading.Lock()
cls._instance._init()
return cls._instance
def __init__(self, config=None):
self.obj_list = []
if config:
self.config = config
def _init(self):
self._pluggy_pm = pluggy.PluginManager("aprsd")
self._pluggy_pm.add_hookspecs(APRSDPluginSpec)
@@ -422,10 +416,10 @@ class PluginManager:
self._watchlist_pm.register(plugin_obj)
else:
LOG.warning(f"Plugin {plugin_obj.__class__.__name__} is disabled")
else:
elif isinstance(plugin_obj, APRSDRegexCommandPluginBase):
if plugin_obj.enabled:
LOG.info(
"Registering plugin '{}'({}) -- {}".format(
"Registering Regex plugin '{}'({}) -- {}".format(
plugin_name,
plugin_obj.version,
plugin_obj.command_regex,
@@ -434,6 +428,17 @@ class PluginManager:
self._pluggy_pm.register(plugin_obj)
else:
LOG.warning(f"Plugin {plugin_obj.__class__.__name__} is disabled")
elif isinstance(plugin_obj, APRSDPluginBase):
if plugin_obj.enabled:
LOG.info(
"Registering Base plugin '{}'({})".format(
plugin_name,
plugin_obj.version,
),
)
self._pluggy_pm.register(plugin_obj)
else:
LOG.warning(f"Plugin {plugin_obj.__class__.__name__} is disabled")
except Exception as ex:
LOG.error(f"Couldn't load plugin '{plugin_name}'")
LOG.exception(ex)
@@ -443,14 +448,14 @@ class PluginManager:
del self._pluggy_pm
self.setup_plugins()
def setup_plugins(self):
def setup_plugins(self, load_help_plugin=True):
"""Create the plugin manager and register plugins."""
LOG.info("Loading APRSD Plugins")
self._init()
# Help plugin is always enabled.
_help = HelpPlugin()
self._pluggy_pm.register(_help)
if load_help_plugin:
_help = HelpPlugin()
self._pluggy_pm.register(_help)
enabled_plugins = CONF.enabled_plugins
if enabled_plugins:
@@ -465,7 +470,7 @@ class PluginManager:
LOG.info("Completed Plugin Loading.")
def run(self, packet: packets.core.MessagePacket):
"""Execute all the pluguns run method."""
"""Execute all the plugins run method."""
with self.lock:
return self._pluggy_pm.hook.filter(packet=packet)
@@ -482,7 +487,8 @@ class PluginManager:
def register_msg(self, obj):
"""Register the plugin."""
self._pluggy_pm.register(obj)
with self.lock:
self._pluggy_pm.register(obj)
def get_plugins(self):
plugin_list = []
+1
View File
@@ -62,6 +62,7 @@ class APRSDService(rpyc.Service):
def get_stats(self):
stat = stats.APRSDStats()
stats_dict = stat.stats()
LOG.debug(stats_dict)
return json.dumps(stats_dict, indent=4, sort_keys=True, default=str)
@rpyc.exposed
+1
View File
@@ -233,6 +233,7 @@ class APRSDStats:
},
"plugins": plugin_stats,
}
LOG.debug(f"STATS = {stats}")
return stats
def __str__(self):
+4
View File
@@ -66,6 +66,10 @@ class APRSDThread(threading.Thread, metaclass=abc.ABCMeta):
def _cleanup(self):
"""Add code to subclass to do any cleanup"""
def __str__(self):
out = f"Thread <{self.__class__.__name__}({self.name}) Alive? {self.is_alive()}>"
return out
def run(self):
LOG.debug("Starting")
while not self._should_quit():
+25 -12
View File
@@ -64,22 +64,35 @@ class KeepAliveThread(APRSDThread):
len(thread_list),
)
LOG.info(keepalive)
thread_out = []
for thread in thread_list.threads_list:
alive = thread.is_alive()
thread_out.append(f"{thread.__class__.__name__}:{alive}")
if not alive:
LOG.error(f"Thread {thread}")
LOG.info(",".join(thread_out))
# See if we should reset the aprs-is client
# Due to losing a keepalive from them
delta_dict = utils.parse_delta_str(last_msg_time)
delta = datetime.timedelta(**delta_dict)
# check the APRS connection
cl = client.factory.create()
if not cl.is_alive():
LOG.error(f"{cl.__class__.__name__} is not alive!!! Resetting")
client.factory.create().reset()
else:
# See if we should reset the aprs-is client
# Due to losing a keepalive from them
delta_dict = utils.parse_delta_str(last_msg_time)
delta = datetime.timedelta(**delta_dict)
if delta > self.max_delta:
# We haven't gotten a keepalive from aprs-is in a while
# reset the connection.a
if not client.KISSClient.is_enabled():
LOG.warning(f"Resetting connection to APRS-IS {delta}")
client.factory.create().reset()
if delta > self.max_delta:
# We haven't gotten a keepalive from aprs-is in a while
# reset the connection.a
if not client.KISSClient.is_enabled():
LOG.warning(f"Resetting connection to APRS-IS {delta}")
client.factory.create().reset()
# Check version every hour
# Check version every day
delta = now - self.checker_time
if delta > datetime.timedelta(hours=1):
if delta > datetime.timedelta(hours=24):
self.checker_time = now
level, msg = utils._check_version()
if level:
+1
View File
@@ -65,6 +65,7 @@ class APRSDPluginRXThread(APRSDRXThread):
receives packets from APRIS and then sends them for
processing in the PluginProcessPacketThread.
"""
def process_packet(self, *args, **kwargs):
packet = self._client.decode_packet(*args, **kwargs)
# LOG.debug(raw)
+38 -11
View File
@@ -2,34 +2,61 @@ import datetime
import logging
import time
from oslo_config import cfg
from ratelimiter import RateLimiter
from aprsd import client
from aprsd import threads as aprsd_threads
from aprsd.packets import core, tracker
CONF = cfg.CONF
LOG = logging.getLogger("APRSD")
def limited(until):
duration = int(round(until - time.time()))
LOG.debug(f"Rate limited, sleeping for {duration:d} seconds")
def send(packet: core.Packet, direct=False, aprs_client=None):
"""Send a packet either in a thread or directly to the client."""
# prepare the packet for sending.
# This constructs the packet.raw
packet.prepare()
if isinstance(packet, core.AckPacket):
_send_ack(packet, direct=direct, aprs_client=aprs_client)
else:
_send_packet(packet, direct=direct, aprs_client=aprs_client)
@RateLimiter(max_calls=1, period=CONF.msg_rate_limit_period, callback=limited)
def _send_packet(packet: core.Packet, direct=False, aprs_client=None):
if not direct:
if isinstance(packet, core.AckPacket):
thread = SendAckThread(packet=packet)
else:
thread = SendPacketThread(packet=packet)
thread = SendPacketThread(packet=packet)
thread.start()
else:
if aprs_client:
cl = aprs_client
else:
cl = client.factory.create()
_send_direct(packet, aprs_client=aprs_client)
packet.update_timestamp()
packet.log(header="TX")
cl.send(packet)
@RateLimiter(max_calls=1, period=CONF.ack_rate_limit_period, callback=limited)
def _send_ack(packet: core.AckPacket, direct=False, aprs_client=None):
if not direct:
thread = SendAckThread(packet=packet)
thread.start()
else:
_send_direct(packet, aprs_client=aprs_client)
def _send_direct(packet, aprs_client=None):
if aprs_client:
cl = aprs_client
else:
cl = client.factory.create()
packet.update_timestamp()
packet.log(header="TX")
cl.send(packet)
class SendPacketThread(aprsd_threads.APRSDThread):
+18 -18
View File
@@ -5,22 +5,22 @@
# pip-compile --annotation-style=line --resolver=backtracking dev-requirements.in
#
add-trailing-comma==2.4.0 # via gray
alabaster==0.7.12 # via sphinx
alabaster==0.7.13 # via sphinx
attrs==22.2.0 # via jsonschema, pytest
autoflake==1.5.3 # via gray
babel==2.11.0 # via sphinx
black==22.12.0 # via gray
build==0.9.0 # via pip-tools
cachetools==5.2.0 # via tox
build==0.10.0 # via pip-tools
cachetools==5.2.1 # via tox
certifi==2022.12.7 # via requests
cfgv==3.3.1 # via pre-commit
chardet==5.1.0 # via tox
charset-normalizer==2.1.1 # via requests
charset-normalizer==3.0.1 # via requests
click==8.1.3 # via black, pip-tools
colorama==0.4.6 # via tox
commonmark==0.9.1 # via rich
configargparse==1.5.3 # via gray
coverage[toml]==7.0.3 # via pytest-cov
coverage[toml]==7.0.5 # via pytest-cov
distlib==0.3.6 # via virtualenv
docutils==0.19 # via sphinx
exceptiongroup==1.1.0 # via pytest
@@ -28,7 +28,7 @@ filelock==3.9.0 # via tox, virtualenv
fixit==0.1.4 # via gray
flake8==6.0.0 # via -r dev-requirements.in, fixit, pep8-naming
gray==0.13.0 # via -r dev-requirements.in
identify==2.5.12 # via pre-commit
identify==2.5.13 # via pre-commit
idna==3.4 # via requests
imagesize==1.4.1 # via sphinx
importlib-metadata==6.0.0 # via sphinx
@@ -38,14 +38,13 @@ isort==5.11.4 # via -r dev-requirements.in, gray
jinja2==3.1.2 # via sphinx
jsonschema==4.17.3 # via fixit
libcst==0.4.9 # via fixit
markupsafe==2.1.1 # via jinja2
markupsafe==2.1.2 # via jinja2
mccabe==0.7.0 # via flake8
mypy==0.991 # via -r dev-requirements.in
mypy-extensions==0.4.3 # via black, mypy, typing-inspect
nodeenv==1.7.0 # via pre-commit
packaging==22.0 # via build, pyproject-api, pytest, sphinx, tox
packaging==23.0 # via build, pyproject-api, pytest, sphinx, tox
pathspec==0.10.3 # via black
pep517==0.13.0 # via build
pep8-naming==0.13.3 # via -r dev-requirements.in
pip-tools==6.12.1 # via -r dev-requirements.in
platformdirs==2.6.2 # via black, tox, virtualenv
@@ -54,18 +53,19 @@ pre-commit==2.21.0 # via -r dev-requirements.in
pycodestyle==2.10.0 # via flake8
pyflakes==3.0.1 # via autoflake, flake8
pygments==2.14.0 # via rich, sphinx
pyproject-api==1.4.0 # via tox
pyproject-api==1.5.0 # via tox
pyproject-hooks==1.0.0 # via build
pyrsistent==0.19.3 # via jsonschema
pytest==7.2.0 # via -r dev-requirements.in, pytest-cov
pytest==7.2.1 # via -r dev-requirements.in, pytest-cov
pytest-cov==4.0.0 # via -r dev-requirements.in
pytz==2022.7 # via babel
pytz==2022.7.1 # via babel
pyupgrade==3.3.1 # via gray
pyyaml==6.0 # via fixit, libcst, pre-commit
requests==2.28.1 # via sphinx
requests==2.28.2 # via sphinx
rich==12.6.0 # via gray
snowballstemmer==2.2.0 # via sphinx
sphinx==6.1.2 # via -r dev-requirements.in
sphinxcontrib-applehelp==1.0.2 # via sphinx
sphinx==6.1.3 # via -r dev-requirements.in
sphinxcontrib-applehelp==1.0.3 # via sphinx
sphinxcontrib-devhelp==1.0.2 # via sphinx
sphinxcontrib-htmlhelp==2.0.0 # via sphinx
sphinxcontrib-jsmath==1.0.1 # via sphinx
@@ -73,13 +73,13 @@ sphinxcontrib-qthelp==1.0.3 # via sphinx
sphinxcontrib-serializinghtml==1.1.5 # via sphinx
tokenize-rt==5.0.0 # via add-trailing-comma, pyupgrade
toml==0.10.2 # via autoflake
tomli==2.0.1 # via black, build, coverage, mypy, pep517, pyproject-api, pytest, tox
tox==4.2.6 # via -r dev-requirements.in
tomli==2.0.1 # via black, build, coverage, mypy, pyproject-api, pyproject-hooks, pytest, tox
tox==4.3.5 # via -r dev-requirements.in
typing-extensions==4.4.0 # via black, libcst, mypy, typing-inspect
typing-inspect==0.8.0 # via libcst
unify==0.5 # via gray
untokenize==0.1.1 # via unify
urllib3==1.26.13 # via requests
urllib3==1.26.14 # via requests
virtualenv==20.17.1 # via pre-commit, tox
wheel==0.38.4 # via pip-tools
zipp==3.11.0 # via importlib-metadata, importlib-resources
+4 -3
View File
@@ -37,14 +37,14 @@ RUN if [ "${BUILDX_QEMU_ENV}" = "true" -a "$(getconf LONG_BIT)" = "32" ]; then \
pip3 install cryptography ;\
fi
# Install aprsd
RUN pip3 install aprsd==$APRSD_PIP_VERSION
# Ensure /config is there with a default config file
USER root
# Install aprsd
RUN pip3 install aprsd==$APRSD_PIP_VERSION
RUN mkdir -p /config
RUN aprsd sample-config > /config/aprsd.conf
RUN chown -R $APRS_USER:$APRS_USER /config
RUN chown -R $APRS_USER:$APRS_USER $HOME
# override this to run another configuration
ENV CONF default
@@ -52,6 +52,7 @@ VOLUME ["/config", "/plugins"]
USER $APRS_USER
ADD bin/run.sh /usr/local/bin
ADD bin/listen.sh /usr/local/bin
ENTRYPOINT ["/usr/local/bin/run.sh"]
HEALTHCHECK --interval=5m --timeout=12s --start-period=30s \
+1
View File
@@ -64,6 +64,7 @@ USER $APRS_USER
VOLUME ["/config", "/plugins"]
ADD bin/run.sh $HOME/
ADD bin/listen.sh $HOME/
ENTRYPOINT ["/home/aprs/run.sh"]
HEALTHCHECK --interval=5m --timeout=12s --start-period=30s \
+31
View File
@@ -0,0 +1,31 @@
#!/usr/bin/env bash
set -x
if [ ! -z "${APRSD_PLUGINS}" ]; then
OLDIFS=$IFS
IFS=','
echo "Installing pypi plugins '$APRSD_PLUGINS'";
for plugin in ${APRSD_PLUGINS}; do
IFS=$OLDIFS
# call your procedure/other scripts here below
echo "Installing '$plugin'"
pip3 install $plugin
done
fi
if [ -z "${LOG_LEVEL}" ] || [[ ! "${LOG_LEVEL}" =~ ^(CRITICAL|ERROR|WARNING|INFO)$ ]]; then
LOG_LEVEL="DEBUG"
fi
echo "Log level is set to ${LOG_LEVEL}";
# check to see if there is a config file
APRSD_CONFIG="/config/aprsd.conf"
if [ ! -e "$APRSD_CONFIG" ]; then
echo "'$APRSD_CONFIG' File does not exist. Creating."
aprsd sample-config > $APRSD_CONFIG
fi
export COLUMNS=200
python3 -m rich.diagnose
exec aprsd listen -c $APRSD_CONFIG --loglevel ${LOG_LEVEL} ${APRSD_LOAD_PLUGINS} ${APRSD_LISTEN_FILTER}
+4 -2
View File
@@ -16,6 +16,7 @@ OPTIONS:
-d Use Dockerfile-dev for a git clone build
-b Branch to use (default = master)
-r Destroy and rebuild the buildx environment
-v aprsd version to build
EOF
}
@@ -62,8 +63,9 @@ done
if [ $ALL_PLATFORMS -eq 1 ]
then
PLATFORMS="linux/arm/v7,linux/arm64,linux/amd64"
PLATFORMS="linux/arm64,linux/amd64"
#PLATFORMS="linux/arm/v7,linux/arm/v6,linux/amd64"
#PLATFORMS="linux/arm64"
else
PLATFORMS="linux/amd64"
fi
@@ -87,7 +89,7 @@ then
echo "Build -DEV- with tag=${TAG} BRANCH=${BRANCH} platforms?=${PLATFORMS}"
# Use this script to locally build the docker image
docker buildx build --push --platform $PLATFORMS \
-t harbor.hemna.com/hemna6969/aprsd:$TAG \
-t hemna6969/aprsd:$TAG \
-f Dockerfile-dev --build-arg branch=$BRANCH \
--build-arg BUILDX_QEMU_ENV=true \
--no-cache .
+1
View File
@@ -36,3 +36,4 @@ rpyc
# raspi
cryptography==38.0.1
shellingham==1.5.0.post1
ratelimiter
+9 -8
View File
@@ -12,7 +12,7 @@ bidict==0.22.1 # via python-socketio
bitarray==2.6.2 # via ax253, kiss3
certifi==2022.12.7 # via requests
cffi==1.15.1 # via cryptography
charset-normalizer==2.1.1 # via requests
charset-normalizer==3.0.1 # via requests
click==8.1.3 # via -r requirements.in, click-completion, flask
click-completion==0.5.2 # via -r requirements.in
commonmark==0.9.1 # via rich
@@ -20,8 +20,8 @@ cryptography==38.0.1 # via -r requirements.in, pyopenssl
dacite2==2.0.0 # via -r requirements.in
dataclasses==0.6 # via -r requirements.in
debtcollector==2.5.0 # via oslo-config
dnspython==2.2.1 # via eventlet
eventlet==0.33.2 # via -r requirements.in
dnspython==2.3.0 # via eventlet
eventlet==0.33.3 # via -r requirements.in
flask==2.1.2 # via -r requirements.in, flask-classful, flask-httpauth, flask-socketio
flask-classful==0.14.2 # via -r requirements.in
flask-httpauth==4.7.0 # via -r requirements.in
@@ -33,11 +33,11 @@ importlib-metadata==6.0.0 # via ax253, flask, kiss3
itsdangerous==2.1.2 # via flask
jinja2==3.1.2 # via click-completion, flask
kiss3==8.0.0 # via -r requirements.in
markupsafe==2.1.1 # via jinja2
markupsafe==2.1.2 # via jinja2
netaddr==0.8.0 # via oslo-config
oslo-config==9.1.0 # via -r requirements.in
oslo-i18n==5.1.0 # via oslo-config
pbr==5.11.0 # via -r requirements.in, oslo-i18n, stevedore
pbr==5.11.1 # via -r requirements.in, oslo-i18n, stevedore
pluggy==1.0.0 # via -r requirements.in
plumbum==1.8.1 # via rpyc
pycparser==2.21 # via cffi
@@ -47,9 +47,10 @@ pyserial==3.5 # via pyserial-asyncio
pyserial-asyncio==0.6 # via kiss3
python-engineio==4.3.4 # via python-socketio
python-socketio==5.7.2 # via flask-socketio
pytz==2022.7 # via -r requirements.in
pytz==2022.7.1 # via -r requirements.in
pyyaml==6.0 # via -r requirements.in, oslo-config
requests==2.28.1 # via -r requirements.in, oslo-config, update-checker
ratelimiter==1.2.0.post0 # via -r requirements.in
requests==2.28.2 # via -r requirements.in, oslo-config, update-checker
rfc3986==2.0.0 # via oslo-config
rich==12.6.0 # via -r requirements.in
rpyc==5.3.0 # via -r requirements.in
@@ -61,7 +62,7 @@ tabulate==0.9.0 # via -r requirements.in
thesmuggler==1.0.1 # via -r requirements.in
ua-parser==0.16.1 # via user-agents
update-checker==0.18.0 # via -r requirements.in
urllib3==1.26.13 # via requests
urllib3==1.26.14 # via requests
user-agents==2.2.0 # via -r requirements.in
werkzeug==2.1.2 # via -r requirements.in, flask
wrapt==1.14.1 # via -r requirements.in, debtcollector