sysrepo-python-plugind 1.0.0__tar.gz → 1.0.1__tar.gz

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (24) hide show
  1. {sysrepo_python_plugind-1.0.0/src/sysrepo_python_plugind.egg-info → sysrepo_python_plugind-1.0.1}/PKG-INFO +1 -1
  2. {sysrepo_python_plugind-1.0.0 → sysrepo_python_plugind-1.0.1}/pyproject.toml +1 -1
  3. sysrepo_python_plugind-1.0.1/setup.cfg +38 -0
  4. {sysrepo_python_plugind-1.0.0 → sysrepo_python_plugind-1.0.1}/src/sysrepo_python_plugind/cli.py +8 -2
  5. {sysrepo_python_plugind-1.0.0 → sysrepo_python_plugind-1.0.1}/src/sysrepo_python_plugind/daemon.py +25 -3
  6. {sysrepo_python_plugind-1.0.0 → sysrepo_python_plugind-1.0.1/src/sysrepo_python_plugind.egg-info}/PKG-INFO +1 -1
  7. {sysrepo_python_plugind-1.0.0 → sysrepo_python_plugind-1.0.1}/src/sysrepo_python_plugind.egg-info/SOURCES.txt +1 -0
  8. sysrepo_python_plugind-1.0.0/setup.cfg +0 -4
  9. {sysrepo_python_plugind-1.0.0 → sysrepo_python_plugind-1.0.1}/LICENSE +0 -0
  10. {sysrepo_python_plugind-1.0.0 → sysrepo_python_plugind-1.0.1}/README.rst +0 -0
  11. {sysrepo_python_plugind-1.0.0 → sysrepo_python_plugind-1.0.1}/src/sysrepo_python_plugind/__init__.py +0 -0
  12. {sysrepo_python_plugind-1.0.0 → sysrepo_python_plugind-1.0.1}/src/sysrepo_python_plugind/__main__.py +0 -0
  13. {sysrepo_python_plugind-1.0.0 → sysrepo_python_plugind-1.0.1}/src/sysrepo_python_plugind/install_yang.py +0 -0
  14. {sysrepo_python_plugind-1.0.0 → sysrepo_python_plugind-1.0.1}/src/sysrepo_python_plugind/pid.py +0 -0
  15. {sysrepo_python_plugind-1.0.0 → sysrepo_python_plugind-1.0.1}/src/sysrepo_python_plugind/plugin.py +0 -0
  16. {sysrepo_python_plugind-1.0.0 → sysrepo_python_plugind-1.0.1}/src/sysrepo_python_plugind/sort.py +0 -0
  17. {sysrepo_python_plugind-1.0.0 → sysrepo_python_plugind-1.0.1}/src/sysrepo_python_plugind/yang/sysrepo-python-plugind.yang +0 -0
  18. {sysrepo_python_plugind-1.0.0 → sysrepo_python_plugind-1.0.1}/src/sysrepo_python_plugind.egg-info/dependency_links.txt +0 -0
  19. {sysrepo_python_plugind-1.0.0 → sysrepo_python_plugind-1.0.1}/src/sysrepo_python_plugind.egg-info/entry_points.txt +0 -0
  20. {sysrepo_python_plugind-1.0.0 → sysrepo_python_plugind-1.0.1}/src/sysrepo_python_plugind.egg-info/requires.txt +0 -0
  21. {sysrepo_python_plugind-1.0.0 → sysrepo_python_plugind-1.0.1}/src/sysrepo_python_plugind.egg-info/top_level.txt +0 -0
  22. {sysrepo_python_plugind-1.0.0 → sysrepo_python_plugind-1.0.1}/tests/test_daemon.py +0 -0
  23. {sysrepo_python_plugind-1.0.0 → sysrepo_python_plugind-1.0.1}/tests/test_pid.py +0 -0
  24. {sysrepo_python_plugind-1.0.0 → sysrepo_python_plugind-1.0.1}/tests/test_sort.py +0 -0
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: sysrepo-python-plugind
3
- Version: 1.0.0
3
+ Version: 1.0.1
4
4
  Summary: Python plugin daemon for sysrepo (replacement for sysrepo-plugind)
5
5
  License-Expression: BSD-3-Clause
6
6
  Project-URL: Repository, https://github.com/entrypoint-communications/sysrepo-python-plugind
@@ -4,7 +4,7 @@ build-backend = "setuptools.build_meta"
4
4
 
5
5
  [project]
6
6
  name = "sysrepo-python-plugind"
7
- version = "1.0.0"
7
+ version = "1.0.1"
8
8
  description = "Python plugin daemon for sysrepo (replacement for sysrepo-plugind)"
9
9
  readme = "README.rst"
10
10
  license = "BSD-3-Clause"
@@ -0,0 +1,38 @@
1
+ [metadata]
2
+ name = sysrepo-python-plugind
3
+ version = 1.0.1
4
+ description = Python plugin daemon for sysrepo (replacement for sysrepo-plugind)
5
+ long_description = file: README.rst
6
+ long_description_content_type = text/x-rst
7
+ license = BSD-3-Clause
8
+ project_urls =
9
+ Repository = https://github.com/entrypoint-communications/sysrepo-python-plugind
10
+
11
+ [options]
12
+ python_requires = >=3.10
13
+ packages = find:
14
+ package_dir =
15
+ = src
16
+ install_requires =
17
+ sysrepo~=2.0
18
+
19
+ [options.packages.find]
20
+ where = src
21
+
22
+ [options.entry_points]
23
+ console_scripts =
24
+ sysrepo-python-plugind = sysrepo_python_plugind:main
25
+ sysrepo-python-plugind-setup = sysrepo_python_plugind.install_yang:main
26
+
27
+ [options.package_data]
28
+ sysrepo_python_plugind =
29
+ yang/*.yang
30
+
31
+ [options.extras_require]
32
+ test =
33
+ pytest>=7
34
+
35
+ [egg_info]
36
+ tag_build =
37
+ tag_date = 0
38
+
@@ -73,7 +73,12 @@ def main() -> int:
73
73
  if args.pid_file:
74
74
  return _run_with_pid(daemon, args.pid_file, debug=args.debug)
75
75
 
76
- if not args.debug:
76
+ # When running under systemd (Type=notify), NOTIFY_SOCKET is set and the
77
+ # process must stay in the foreground so READY=1 is sent from the tracked
78
+ # main PID. Daemonizing here would cause systemd to reject the notification
79
+ # from the forked grandchild and fail the service with result 'protocol'.
80
+ under_systemd = bool(os.environ.get("NOTIFY_SOCKET"))
81
+ if not args.debug and not under_systemd:
77
82
  _daemonize()
78
83
  return daemon.run()
79
84
 
@@ -94,9 +99,10 @@ def _run_with_pid(daemon: PluginDaemon, pid_path: str, debug: bool) -> int:
94
99
  int: Exit code from daemon.run(), or 1 if the PID file is already
95
100
  locked by another instance.
96
101
  """
102
+ under_systemd = bool(os.environ.get("NOTIFY_SOCKET"))
97
103
  try:
98
104
  with PidFile(pid_path) as pid_file:
99
- if not debug:
105
+ if not debug and not under_systemd:
100
106
  _daemonize()
101
107
  return daemon.run(pid_file)
102
108
  except RuntimeError as exc:
@@ -92,9 +92,11 @@ class PluginDaemon:
92
92
  LOG.info(
93
93
  "daemon ready, %d plugin(s) loaded", len(self._plugins)
94
94
  )
95
- self._stop.wait()
95
+ while not self._stop.wait(timeout=1.0):
96
+ pass
96
97
  LOG.info("shutting down")
97
98
  _sd_notify("STOPPING=1")
99
+ self._arm_exit_watchdog()
98
100
  self._cleanup_plugins(sess)
99
101
  except Exception:
100
102
  LOG.exception("daemon error")
@@ -104,6 +106,25 @@ class PluginDaemon:
104
106
 
105
107
  return rc
106
108
 
109
+ # ------------------------------------------------------------------
110
+ # Shutdown watchdog
111
+
112
+ def _arm_exit_watchdog(self, timeout: float = 10.0) -> None:
113
+ """Force-exit if sysrepo cleanup stalls longer than *timeout* seconds.
114
+
115
+ Sysrepo's C library waits for its subscription threads to join when
116
+ a session or connection is closed. Those threads can block indefinitely
117
+ if a callback is in-flight or stuck in a poll. The watchdog fires
118
+ os._exit() so the process never has to wait for SIGKILL from systemd.
119
+ """
120
+ def _force() -> None:
121
+ LOG.warning("cleanup stalled after %.0f s, forcing exit", timeout)
122
+ os._exit(1)
123
+
124
+ t = threading.Timer(timeout, _force)
125
+ t.daemon = True
126
+ t.start()
127
+
107
128
  # ------------------------------------------------------------------
108
129
  # Signal handling
109
130
 
@@ -116,10 +137,11 @@ class PluginDaemon:
116
137
  ignored.
117
138
  """
118
139
  def _handler(sig: int, _frame) -> None:
140
+ sig_name = signal.Signals(sig).name
119
141
  if self._stop.is_set():
120
- # Second signal while already shutting down → hard exit.
142
+ LOG.warning("received %s during shutdown, forcing exit", sig_name)
121
143
  sys.exit(1)
122
- LOG.info("received %s, initiating shutdown", signal.Signals(sig).name)
144
+ LOG.warning("received %s, initiating graceful shutdown", sig_name)
123
145
  self._stop.set()
124
146
 
125
147
  for sig in (
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: sysrepo-python-plugind
3
- Version: 1.0.0
3
+ Version: 1.0.1
4
4
  Summary: Python plugin daemon for sysrepo (replacement for sysrepo-plugind)
5
5
  License-Expression: BSD-3-Clause
6
6
  Project-URL: Repository, https://github.com/entrypoint-communications/sysrepo-python-plugind
@@ -1,6 +1,7 @@
1
1
  LICENSE
2
2
  README.rst
3
3
  pyproject.toml
4
+ setup.cfg
4
5
  src/sysrepo_python_plugind/__init__.py
5
6
  src/sysrepo_python_plugind/__main__.py
6
7
  src/sysrepo_python_plugind/cli.py
@@ -1,4 +0,0 @@
1
- [egg_info]
2
- tag_build =
3
- tag_date = 0
4
-