This repository has been archived on 2025-03-20. You can view files and clone it, but cannot push or open issues or pull requests.
sonic-buildimage/src/sonic-daemon-base/sonic_daemon_base/daemon_base.py
Kevin(Shengkai) Wang fa84c4226b [sonic-daemon-base] Create DaemonBase class for all daemons (#2570)
DaemonBase is to wrap the common function of daemons, such as logging,
signal handling, db connector, load specific platform plugins.

Signed-off-by: Kevin Wang <kevinw@mellanox.com>
2019-03-06 08:55:43 +02:00

137 lines
4.6 KiB
Python

#!/usr/bin/env python2
try:
import imp
import signal
import subprocess
import sys
import syslog
from swsscommon import swsscommon
except ImportError, e:
raise ImportError (str(e) + " - required module not found")
#============================= Constants =============================
# Platform root directory inside docker
PLATFORM_ROOT_DOCKER = "/usr/share/sonic/platform"
SONIC_CFGGEN_PATH = '/usr/local/bin/sonic-cfggen'
HWSKU_KEY = 'DEVICE_METADATA.localhost.hwsku'
PLATFORM_KEY = 'DEVICE_METADATA.localhost.platform'
class DaemonBase(object):
# Redis DB information
redis_hostname = "localhost"
redis_port = 6379
redis_timeout_msecs = 0
def __init__(self):
self.log_info("Starting up...")
# Register our signal handlers
signal.signal(signal.SIGHUP, self.signal_handler)
signal.signal(signal.SIGINT, self.signal_handler)
signal.signal(signal.SIGTERM, self.signal_handler)
def __del__(self):
self.log_error("Return from daemon, exiting...")
def run(self):
raise NotImplementedError()
# ========================== Connect to DB ============================
def db_connect(self, db):
return swsscommon.DBConnector(db,
self.redis_hostname,
self.redis_port,
self.redis_timeout_msecs)
# ========================== Syslog wrappers ==========================
def log_info(self, msg):
syslog.openlog()
syslog.syslog(syslog.LOG_INFO, msg)
syslog.closelog()
def log_warning(self, msg):
syslog.openlog()
syslog.syslog(syslog.LOG_WARNING, msg)
syslog.closelog()
def log_error(self, msg):
syslog.openlog()
syslog.syslog(syslog.LOG_ERR, msg)
syslog.closelog()
#========================== Signal Handling ==========================
def signal_handler(self, sig, frame):
if sig == signal.SIGHUP:
self.log_info("Caught SIGHUP - ignoring...")
return
elif sig == signal.SIGINT:
self.log_info("Caught SIGINT - exiting...")
sys.exit(128 + sig)
elif sig == signal.SIGTERM:
self.log_info("Caught SIGTERM - exiting...")
sys.exit(128 + sig)
else:
self.log_warning("Caught unhandled signal '" + sig + "'")
return
#============ Functions to load platform-specific classes ============
# Returns platform and HW SKU
def get_platform_and_hwsku(self):
try:
proc = subprocess.Popen([SONIC_CFGGEN_PATH, '-H', '-v', PLATFORM_KEY],
stdout=subprocess.PIPE,
shell=False,
stderr=subprocess.STDOUT)
stdout = proc.communicate()[0]
proc.wait()
platform = stdout.rstrip('\n')
proc = subprocess.Popen([SONIC_CFGGEN_PATH, '-d', '-v', HWSKU_KEY],
stdout=subprocess.PIPE,
shell=False,
stderr=subprocess.STDOUT)
stdout = proc.communicate()[0]
proc.wait()
hwsku = stdout.rstrip('\n')
except OSError, e:
self.log_error("Cannot to detect platform")
raise OSError("Cannot detect platform")
return (platform, hwsku)
# Returns path to hwsku
def get_path_to_platform_and_hwsku(self):
# Get platform and hwsku
(platform, hwsku) = self.get_platform_and_hwsku()
# Load platform module from source
platform_path = PLATFORM_ROOT_DOCKER
hwsku_path = "/".join([platform_path, hwsku])
return (platform_path, hwsku_path)
# Loads platform specific psuutil module from source
def load_platform_util(self, module_name, class_name):
platform_util = None
# Get path to platform and hwsku
(platform_path, hwsku_path) = self.get_path_to_platform_and_hwsku()
try:
module_file = "/".join([platform_path, "plugins", module_name + ".py"])
module = imp.load_source(module_name, module_file)
except IOError, e:
self.log_error("Failed to load platform module '%s': %s" % (module_name, str(e)))
return None
try:
platform_util_class = getattr(module, class_name)
platform_util = platform_util_class()
except AttributeError, e:
self.log_error("Failed to instantiate '%s' class: %s" % (class_name, str(e)))
return None
return platform_util