Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Refactored daemon base API: added Logger. #2672

Merged
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
144 changes: 94 additions & 50 deletions src/sonic-daemon-base/sonic_daemon_base/daemon_base.py
Original file line number Diff line number Diff line change
Expand Up @@ -4,82 +4,111 @@
import imp
import signal
import subprocess
import os
import sys
import syslog
from swsscommon import swsscommon
except ImportError, e:
raise ImportError (str(e) + " - required module not found")

#============================= Constants =============================
#
# Constants ====================================================================
#

# Redis DB information
REDIS_HOSTNAME = 'localhost'
REDIS_PORT = 6379
REDIS_TIMEOUT_MSECS = 0

# Platform root directory inside docker
PLATFORM_ROOT_DOCKER = "/usr/share/sonic/platform"
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'

# Port config information
PORT_CONFIG = 'port_config.ini'
PORTMAP = 'portmap.ini'

EEPROM_MODULE_NAME = 'eeprom'
EEPROM_CLASS_NAME = 'board'

class DaemonBase(object):
# Redis DB information
redis_hostname = "localhost"
redis_port = 6379
redis_timeout_msecs = 0
#
# Helper functions =============================================================
#

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 db_connect(db):
return swsscommon.DBConnector(db,
REDIS_HOSTNAME,
REDIS_PORT,
REDIS_TIMEOUT_MSECS)

#
# Helper classes ===============================================================
#

class Logger(object):
def __init__(self, syslog_identifier):
syslog.openlog(ident=syslog_identifier, logoption=syslog.LOG_NDELAY, facility=syslog.LOG_DAEMON)

def __del__(self):
self.log_error("Return from daemon, exiting...")
syslog.closelog()

def run(self):
raise NotImplementedError()
def log_error(self, msg, also_print_to_console=False):
syslog.syslog(syslog.LOG_ERR, msg)

if also_print_to_console:
print msg

# ========================== Connect to DB ============================
def db_connect(self, db):
return swsscommon.DBConnector(db,
self.redis_hostname,
self.redis_port,
self.redis_timeout_msecs)
def log_warning(self, msg, also_print_to_console=False):
syslog.syslog(syslog.LOG_WARNING, msg)

if also_print_to_console:
print msg

def log_notice(self, msg, also_print_to_console=False):
syslog.syslog(syslog.LOG_NOTICE, msg)

# ========================== Syslog wrappers ==========================
def log_info(self, msg):
syslog.openlog()
if also_print_to_console:
print msg

def log_info(self, msg, also_print_to_console=False):
syslog.syslog(syslog.LOG_INFO, msg)
syslog.closelog()

def log_warning(self, msg):
syslog.openlog()
syslog.syslog(syslog.LOG_WARNING, msg)
syslog.closelog()
if also_print_to_console:
print msg

def log_error(self, msg):
syslog.openlog()
syslog.syslog(syslog.LOG_ERR, msg)
syslog.closelog()
def log_debug(self, msg, also_print_to_console=False):
syslog.syslog(syslog.LOG_DEBUG, msg)

if also_print_to_console:
print msg

#========================== Signal Handling ==========================
#
# Daemon =======================================================================
#

class DaemonBase(object):
def __init__(self):
# 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)

# Signal handler
def signal_handler(self, sig, frame):
if sig == signal.SIGHUP:
self.log_info("Caught SIGHUP - ignoring...")
return
syslog.syslog(syslog.LOG_INFO, "Caught SIGHUP - ignoring...")
elif sig == signal.SIGINT:
self.log_info("Caught SIGINT - exiting...")
syslog.syslog(syslog.LOG_INFO, "Caught SIGINT - exiting...")
sys.exit(128 + sig)
elif sig == signal.SIGTERM:
self.log_info("Caught SIGTERM - exiting...")
syslog.syslog(syslog.LOG_INFO, "Caught SIGTERM - exiting...")
sys.exit(128 + sig)
else:
self.log_warning("Caught unhandled signal '" + sig + "'")
return
syslog.syslog(syslog.LOG_WARNING, "Caught unhandled signal '" + sig + "'")

#============ Functions to load platform-specific classes ============
# Returns platform and HW SKU
# Returns platform and hwsku
def get_platform_and_hwsku(self):
try:
proc = subprocess.Popen([SONIC_CFGGEN_PATH, '-H', '-v', PLATFORM_KEY],
Expand All @@ -98,12 +127,11 @@ def get_platform_and_hwsku(self):
proc.wait()
hwsku = stdout.rstrip('\n')
except OSError, e:
self.log_error("Cannot to detect platform")
raise OSError("Cannot detect platform")
raise OSError("Failed to detect platform: %s" % (str(e)))

return (platform, hwsku)

# Returns path to hwsku
# Returns path to platform and hwsku
def get_path_to_platform_and_hwsku(self):
# Get platform and hwsku
(platform, hwsku) = self.get_platform_and_hwsku()
Expand All @@ -114,6 +142,21 @@ def get_path_to_platform_and_hwsku(self):

return (platform_path, hwsku_path)

# Returns path to port config file
def get_path_to_port_config_file(self):
# Get platform and hwsku path
(platform_path, hwsku_path) = self.get_path_to_platform_and_hwsku()

# First check for the presence of the new 'port_config.ini' file
port_config_file_path = "/".join([hwsku_path, PORT_CONFIG])
if not os.path.isfile(port_config_file_path):
# port_config.ini doesn't exist. Try loading the legacy 'portmap.ini' file
port_config_file_path = "/".join([hwsku_path, PORTMAP])
if not os.path.isfile(port_config_file_path):
raise IOError("Failed to detect port config file: %s" % (port_config_file_path))

return port_config_file_path

# Loads platform specific psuutil module from source
def load_platform_util(self, module_name, class_name):
platform_util = None
Expand All @@ -125,8 +168,7 @@ def load_platform_util(self, module_name, class_name):
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
raise IOError("Failed to load platform module '%s': %s" % (module_name, str(e)))

try:
platform_util_class = getattr(module, class_name)
Expand All @@ -136,8 +178,10 @@ def load_platform_util(self, module_name, class_name):
else:
platform_util = platform_util_class()
except AttributeError, e:
self.log_error("Failed to instantiate '%s' class: %s" % (class_name, str(e)))
return None
raise AttributeError("Failed to instantiate '%s' class: %s" % (class_name, str(e)))

return platform_util

# Runs daemon
def run(self):
raise NotImplementedError()
2 changes: 1 addition & 1 deletion src/sonic-platform-daemons