Python plugin daemon for sysrepo (replacement for sysrepo-plugind)
Project description
A Python reimplementation of sysrepo-plugind — the sysrepo plugin daemon.
The C daemon loads compiled .so plugins via dlopen. This daemon loads Python plugins discovered via entry points (importlib.metadata), giving plugin authors a pure-Python development experience against the existing sysrepo-python CFFI bindings.
The two daemons can run simultaneously: the Python daemon manages its own YANG subtree (python-plugin-order, python-loaded-plugins) and never touches the C daemon’s nodes.
Requirements
Python ≥ 3.10
sysrepo-python (and the underlying libsysrepo.so)
sysrepo core 4.2.10 (ships sysrepo-plugind@2022-08-26.yang)
Installation
pip install sysrepo-python-plugind
Then register the YANG augmentation module with sysrepo (requires write access to the sysrepo repository, typically run as root):
sysrepo-python-plugind-setup
This is idempotent — safe to run on every deployment or system boot. Pass --force to upgrade the module after a package update.
Writing a plugin
Subclass SysrepoPlugin and implement init(). Register the class via an entry point in your package’s pyproject.toml:
[project.entry-points."sysrepo_python.plugins"]
my-plugin = "my_package.plugin:MyPlugin"
Installing your package makes the plugin visible to the daemon immediately — no copying of files or environment variables required.
Minimal example:
import logging
import sysrepo
from sysrepo_python_plugind import SysrepoPlugin
LOG = logging.getLogger(__name__)
class MyPlugin(SysrepoPlugin):
def init(self, session: sysrepo.SysrepoSession) -> None:
self._counter = 0
session.subscribe_module_change(
"my-module", None, self._on_change, done_only=True
)
session.subscribe_oper_data_request(
"my-module", "/my-module:stats", self._on_oper
)
LOG.info("MyPlugin ready")
def cleanup(self, session: sysrepo.SysrepoSession) -> None:
LOG.info("MyPlugin stopping (counter=%d)", self._counter)
def _on_change(self, event, req_id, changes, priv):
self._counter += 1
def _on_oper(self, xpath, priv):
return {"my-module": {"stats": {"change-count": self._counter}}}
State that the C daemon stored in void *private_data is stored as instance attributes (self._counter above).
Async callbacks
The daemon starts an asyncio event loop in a background thread before calling any init(), so plugins can use asyncio_register=True subscriptions without managing a loop themselves:
class AsyncMyPlugin(SysrepoPlugin):
def init(self, session: sysrepo.SysrepoSession) -> None:
session.subscribe_module_change(
"my-module", None, self._on_change,
done_only=True, asyncio_register=True,
)
async def _on_change(self, event, req_id, changes, priv):
...
Running the daemon
# Foreground, INFO-level logging to stderr:
sysrepo-python-plugind -d -v 2
# Background (daemonize), write PID file:
sysrepo-python-plugind -p /run/sysrepo-python-plugind.pid
CLI flags mirror those of the C sysrepo-plugind:
-d |
Stay in foreground; log to stderr instead of syslog |
-v LEVEL |
Verbosity: 0=ERROR 1=WARNING 2=INFO 3=DEBUG (default: 2) |
-p PATH |
Write PID file at PATH |
-f |
Exit if any plugin fails to initialise (default: skip and continue) |
Plugin ordering
By default plugins are initialised in entry-point discovery order. To override this, set the python-plugin-order leaf-list in sysrepo’s running datastore:
sysrepocfg -d running --edit
Add under /sysrepo-plugind:sysrepo-plugind:
<python-plugin-order xmlns="urn:sysrepo:python-plugind">
<plugin>my-plugin</plugin>
<plugin>other-plugin</plugin>
</python-plugin-order>
Plugins absent from the list are appended after the ordered set, preserving their discovery order. A trailing file extension in a configured name (e.g. my-plugin.so) is stripped before comparison, so operator configs written for the C daemon can be reused unchanged.
The list of successfully initialised plugins is published to the operational datastore at /sysrepo-plugind:sysrepo-plugind/sysrepo-python-plugind:python-loaded-plugins/plugin.
Systemd deployment
A service file is provided in the systemd/ directory of the source distribution:
cp systemd/sysrepo-python-plugind.service /etc/systemd/system/
systemctl daemon-reload
systemctl enable --now sysrepo-python-plugind
The service runs sysrepo-python-plugind-setup as ExecStartPre=, ensuring the YANG module is present before the daemon starts.
If the daemon binary is not at /usr/bin/sysrepo-python-plugind (e.g. when installed into a virtual environment), update the ExecStartPre= and ExecStart= paths in the service file accordingly.
License
BSD-3-Clause — same as sysrepo-python.
Project details
Release history Release notifications | RSS feed
Download files
Download the file for your platform. If you're not sure which to choose, learn more about installing packages.
Source Distribution
Built Distribution
Filter files by name, interpreter, ABI, and platform.
If you're not sure about the file name format, learn more about wheel file names.
Copy a direct link to the current filters
File details
Details for the file sysrepo_python_plugind-1.0.0.tar.gz.
File metadata
- Download URL: sysrepo_python_plugind-1.0.0.tar.gz
- Upload date:
- Size: 17.7 kB
- Tags: Source
- Uploaded using Trusted Publishing? Yes
- Uploaded via: twine/6.1.0 CPython/3.13.12
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
96a790c7ddc8a5884f4fc378c87734e665e1905c0f8fc62958a9969ece186748
|
|
| MD5 |
f066d3c8ba58bef8cf8097dbb8890c63
|
|
| BLAKE2b-256 |
adebc74e3ef169f3433097a2090b9a5607ebb871281912246bbc16b23d823729
|
Provenance
The following attestation bundles were made for sysrepo_python_plugind-1.0.0.tar.gz:
Publisher:
python-publish.yml on entrypoint-communications/sysrepo-python-plugind
-
Statement:
-
Statement type:
https://in-toto.io/Statement/v1 -
Predicate type:
https://docs.pypi.org/attestations/publish/v1 -
Subject name:
sysrepo_python_plugind-1.0.0.tar.gz -
Subject digest:
96a790c7ddc8a5884f4fc378c87734e665e1905c0f8fc62958a9969ece186748 - Sigstore transparency entry: 1823574001
- Sigstore integration time:
-
Permalink:
entrypoint-communications/sysrepo-python-plugind@87edd3380bf9464c8606c6138383d37861851057 -
Branch / Tag:
refs/tags/v1.0.0 - Owner: https://github.com/entrypoint-communications
-
Access:
public
-
Token Issuer:
https://token.actions.githubusercontent.com -
Runner Environment:
github-hosted -
Publication workflow:
python-publish.yml@87edd3380bf9464c8606c6138383d37861851057 -
Trigger Event:
push
-
Statement type:
File details
Details for the file sysrepo_python_plugind-1.0.0-py3-none-any.whl.
File metadata
- Download URL: sysrepo_python_plugind-1.0.0-py3-none-any.whl
- Upload date:
- Size: 17.3 kB
- Tags: Python 3
- Uploaded using Trusted Publishing? Yes
- Uploaded via: twine/6.1.0 CPython/3.13.12
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
f97b4b2fac689a528a719a70c1fea0b84196297276477fe24fbe6c7659d875bc
|
|
| MD5 |
766082d2c28325cb3bff96d0c8e6111e
|
|
| BLAKE2b-256 |
afb99fee3ccbef4384c9c1b038eb71d576ce7796ccf58912087c71eac45e8d78
|
Provenance
The following attestation bundles were made for sysrepo_python_plugind-1.0.0-py3-none-any.whl:
Publisher:
python-publish.yml on entrypoint-communications/sysrepo-python-plugind
-
Statement:
-
Statement type:
https://in-toto.io/Statement/v1 -
Predicate type:
https://docs.pypi.org/attestations/publish/v1 -
Subject name:
sysrepo_python_plugind-1.0.0-py3-none-any.whl -
Subject digest:
f97b4b2fac689a528a719a70c1fea0b84196297276477fe24fbe6c7659d875bc - Sigstore transparency entry: 1823574023
- Sigstore integration time:
-
Permalink:
entrypoint-communications/sysrepo-python-plugind@87edd3380bf9464c8606c6138383d37861851057 -
Branch / Tag:
refs/tags/v1.0.0 - Owner: https://github.com/entrypoint-communications
-
Access:
public
-
Token Issuer:
https://token.actions.githubusercontent.com -
Runner Environment:
github-hosted -
Publication workflow:
python-publish.yml@87edd3380bf9464c8606c6138383d37861851057 -
Trigger Event:
push
-
Statement type: