File: //opt/imunify360/venv/lib64/python3.11/site-packages/defence360agent/subsys/systemd_notifier.py
"""Notify systemd about process state"""
import logging
import os
import socket
from defence360agent.contracts.config import ANTIVIRUS_MODE
logger = logging.getLogger(__name__)
_notify_socket_addr = None
_socket_detached = False
class AgentState(object):
"""Allowed agent state for notifying systemd."""
READY = "READY=1"
STARTING = "STATUS=Starting main process"
MIGRATING = "STATUS=Applying database migrations"
DAEMONIZED = "STATUS=Demonized"
def _take_notify_socket():
# Capture $NOTIFY_SOCKET once and drop it from the environment, so child
# processes (systemctl and other libsystemd-aware tools) do not inherit it
# and emit sd_notify datagrams systemd cannot attribute to this unit.
global _notify_socket_addr, _socket_detached
if not _socket_detached:
_notify_socket_addr = os.environ.pop("NOTIFY_SOCKET", None)
_socket_detached = True
return _notify_socket_addr
def notify(state):
"""
Send notification to systemd, allowed formats described here
https://www.freedesktop.org/software/systemd/man/sd_notify.html
For example:
notify("STATUS=Almost ready")
"""
if ANTIVIRUS_MODE:
return
addr = _take_notify_socket()
if not addr:
return
# systemd uses the abstract socket namespace when the path begins with '@'.
connect_addr = "\0" + addr[1:] if addr.startswith("@") else addr
try:
with socket.socket(
socket.AF_UNIX, socket.SOCK_DGRAM | socket.SOCK_CLOEXEC
) as sock:
sock.connect(connect_addr)
sock.sendall(state.encode())
except OSError as e:
logger.exception(
"some problem has occurred during notifying of systemd: %s",
e,
)