diff --git a/main.py b/main.py index dd2328f9fcb193c878c6c384ba1d67f300497836..70eaec461f2b178b18dd5f6c2c8715d6058721f5 100644 --- a/main.py +++ b/main.py @@ -7,7 +7,7 @@ import getopt from settingsd import const from settingsd import validators -from settingsd import startup +from settingsd import application from settingsd import daemon @@ -86,6 +86,6 @@ if __name__ == "__main__" : ##### - startup_proc = startup.Startup(log_level, use_syslog_flag, bus_type, daemon_mode_flag) - startup_proc.run() + app = application.Application(log_level, use_syslog_flag, bus_type, daemon_mode_flag) + app.run() diff --git a/settingsd/application.py b/settingsd/application.py index bfe45e6997ce1e5b6307b477c2f4fb3a193a2fe1..7d01bad72b8b27a2e58068c85477f913a0f06797 100644 --- a/settingsd/application.py +++ b/settingsd/application.py @@ -3,120 +3,115 @@ import sys import os -import dbus -import dbus.service -import dbus.glib -import gobject +import signal +import syslog import const import config -import validators import logger +import server +import daemon ##### Public classes ##### class Application(object) : - def __init__(self) : + def __init__(self, log_level, use_syslog_flag, bus_type, daemon_mode_flag) : object.__init__(self) ##### - self._modules_list = [] - self._services_dict = {} + self._log_level = log_level + self._use_syslog_flag = use_syslog_flag + self._bus_type = bus_type + self._daemon_mode_flag = daemon_mode_flag - self._main_loop = gobject.MainLoop() + ##### + + self._server = server.Server() ### Public ### - def runLoop(self) : - logger.verbose("Running GObject loop...") - self._main_loop.run() + def run(self) : + self.prepare() + if self._daemon_mode_flag : + self.runDaemon() + else : + self.runInteractive() - def quitLoop(self) : - self._main_loop.quit() - logger.verbose("GObject loop closed") + def server(self) : + return self._server ### - def loadModules(self) : - sys.path.append(const.FUNCTIONS_DIR) - sys.path.append(const.ACTIONS_DIR) + def quit(self, signum = None, frame = None) : + if signum != None : + logger.info("Recieved signal %d, closing..." % (signum)) - for modules_path_list_item in (const.FUNCTIONS_DIR, const.ACTIONS_DIR) : - for module_name in [ item[:-3] for item in os.listdir(modules_path_list_item) if item.endswith(".py") ] : - try : - self._modules_list.append(__import__(module_name, globals(), locals(), [""])) - except : - logger.error("Import error on module \"%s\"" % (module_name)) - logger.attachException() - continue + self._server.closeServices() + self._server.quitLoop() + logger.info("Closed") - self._services_dict[self._modules_list[-1].Service.serviceName()] = { - "service_class" : self._modules_list[-1].Service, - "service" : None - } - logger.verbose("Loaded module: %s" % (module_name)) + ### Private ### - sys.path.remove(const.FUNCTIONS_DIR) - sys.path.remove(const.ACTIONS_DIR) + def prepare(self) : + if self._use_syslog_flag == None : + if self._daemon_mode_flag : + syslog.openlog(const.MY_NAME, syslog.LOG_PID, syslog.LOG_DAEMON) + config.setValue(config.RUNTIME_SECTION, "use_syslog", True) + else : + syslog.openlog(const.MY_NAME, syslog.LOG_PID, ( syslog.LOG_DAEMON if self._daemon_mode_flag else syslog.LOG_USER )) + config.setValue(config.RUNTIME_SECTION, "use_syslog", True) - ### - - def loadApplicationConfigs(self) : - config.loadConfigs(only_sections_list = (config.APPLICATION_SECTION,)) + try : + self._server.loadServerConfigs() + except : + logger.error("Initialization error") + logger.attachException() + raise - def loadServicesConfigs(self) : - for service_name in self._services_dict.keys() : - service_options_list = list(self._services_dict[service_name]["service_class"].optionsList()) - service_options_list.append((service_name, "enabled", "no", validators.validBool)) + if self._bus_type != None : + config.setValue(config.APPLICATION_SECTION, "bus_type", self._bus_type) - for service_options_list_item in service_options_list : - try : - config.setValue(*service_options_list_item) - except : - logger.error("Error on set options tuple %s" % (str(service_options_list_item))) - logger.attachException() + if self._log_level != None : + config.setValue(config.APPLICATION_SECTION, "log_level", self._log_level) - config.loadConfigs(exclude_sections_list = (config.APPLICATION_SECTION,)) + config.setValue(config.RUNTIME_SECTION, "application", self) ### - def initBus(self) : - bus_type = config.value(config.APPLICATION_SECTION, "bus_type") - service_name = config.value(config.APPLICATION_SECTION, "service_name") - + def runInteractive(self) : try : - config.setValue(config.RUNTIME_SECTION, "bus_name", dbus.service.BusName(service_name, - ( dbus.SystemBus() if bus_type == const.BUS_TYPE_SYSTEM else dbus.SessionBus() ))) + self._server.loadModules() + self._server.loadServicesConfigs() + self._server.initBus() + self._server.initServices() + logger.info("Initialized") except : - logger.error("Could not connect to D-Bus \"%s\"" % (bus_type)) + logger.error("Initialization error") logger.attachException() raise - logger.verbose("Connected to D-Bus \"%s\" as \"%s\"" % (bus_type, service_name)) + try : + signal.signal(signal.SIGTERM, self.quit) + signal.signal(signal.SIGQUIT, self.quit) + except : + logger.error("signal() error") + logger.attachException() - ### + try : + self._server.runLoop() + except (SystemExit, KeyboardInterrupt) : + self.quit() + except : + logger.error("Runtime error, trying to close services") + logger.attachException() + self.quit() + raise - def initServices(self) : - for service_name in self._services_dict.keys() : - if config.value(service_name, "enabled") : - try : - self._services_dict[service_name]["service"] = self._services_dict[service_name]["service_class"]() - self._services_dict[service_name]["service"].initService() - except : - logger.error("Cannot initialize service \"%s\"" % (service_name)) - logger.attachException() - - def closeServices(self) : - for service_name in self._services_dict.keys() : - if self._services_dict[service_name]["service"] != None : - try : - self._services_dict[service_name]["service"].closeService() - del self._services_dict[service_name]["service"] - except : - logger.error("Cannot close service \"%s\"" % (service_name)) - logger.attachException() - self._services_dict[service_name]["service"] = None + def runDaemon(self) : + work_dir_path = ( "/" if os.getuid() == 0 else None ) + umask = ( 077 if os.getuid() == 0 else None ) + daemon.startDaemon(self.runInteractive, work_dir_path, umask) diff --git a/settingsd/config.py b/settingsd/config.py index 46f0e3edd4c46b8e6b1dea11b1d58ce7a763e6cb..f731d67fa21893765ff5036cdb660629220afc85 100644 --- a/settingsd/config.py +++ b/settingsd/config.py @@ -29,7 +29,6 @@ ConfigDictObject = { }, RUNTIME_SECTION : { "application" : (None, None), - "startup" : (None, None), "bus_name" : (None, None), "use_syslog" : (False, None) } diff --git a/settingsd/logger.py b/settingsd/logger.py index de7dde279d9aa04aafc58e059d146613a4c2a38f..cd52c57d18b663e966f54f29eeac4e1b42127cd9 100644 --- a/settingsd/logger.py +++ b/settingsd/logger.py @@ -40,12 +40,12 @@ def log(message_type, message) : if message_type[2] <= config.value(config.APPLICATION_SECTION, "log_level") : use_colors_flag = sys.stderr.isatty() and config.value(config.APPLICATION_SECTION, "log_use_colors") message_type_texts_list = ( - ( "\033[31mError \033[0m" if use_colors_flag else "Error " ), + ( "\033[31m Error \033[0m" if use_colors_flag else " Error " ), ( "\033[33mWarning\033[0m" if use_colors_flag else "Warning" ), ( "\033[32mNotice \033[0m" if use_colors_flag else "Notice " ), - ( "\033[32mInfo \033[0m" if use_colors_flag else "Info " ), + ( "\033[32m Info \033[0m" if use_colors_flag else " Info " ), ( "\033[36mDetails\033[0m" if use_colors_flag else "Details" ), - "Debug" + " Debug " ) for message_list_item in message.split("\n") : diff --git a/settingsd/server.py b/settingsd/server.py new file mode 100644 index 0000000000000000000000000000000000000000..269b21a5953aeff77257c0c505ff85003390067e --- /dev/null +++ b/settingsd/server.py @@ -0,0 +1,122 @@ +# -*- coding: utf-8 -*- + + +import sys +import os +import dbus +import dbus.service +import dbus.glib +import gobject + +import const +import config +import validators +import logger + + +##### Public classes ##### +class Server(object) : + def __init__(self) : + object.__init__(self) + + ##### + + self._modules_list = [] + self._services_dict = {} + + self._main_loop = gobject.MainLoop() + + + ### Public ### + + def runLoop(self) : + logger.verbose("Running GObject loop...") + self._main_loop.run() + + def quitLoop(self) : + self._main_loop.quit() + logger.verbose("GObject loop closed") + + ### + + def loadModules(self) : + sys.path.append(const.FUNCTIONS_DIR) + sys.path.append(const.ACTIONS_DIR) + + for modules_path_list_item in (const.FUNCTIONS_DIR, const.ACTIONS_DIR) : + for module_name in [ item[:-3] for item in os.listdir(modules_path_list_item) if item.endswith(".py") ] : + try : + self._modules_list.append(__import__(module_name, globals(), locals(), [""])) + except : + logger.error("Import error on module \"%s\"" % (module_name)) + logger.attachException() + continue + + self._services_dict[self._modules_list[-1].Service.serviceName()] = { + "service_class" : self._modules_list[-1].Service, + "service" : None + } + + logger.verbose("Loaded module: %s" % (module_name)) + + sys.path.remove(const.FUNCTIONS_DIR) + sys.path.remove(const.ACTIONS_DIR) + + ### + + def loadServerConfigs(self) : + config.loadConfigs(only_sections_list = (config.APPLICATION_SECTION,)) + + def loadServicesConfigs(self) : + for service_name in self._services_dict.keys() : + service_options_list = list(self._services_dict[service_name]["service_class"].optionsList()) + service_options_list.append((service_name, "enabled", "no", validators.validBool)) + + for service_options_list_item in service_options_list : + try : + config.setValue(*service_options_list_item) + except : + logger.error("Error on set options tuple %s" % (str(service_options_list_item))) + logger.attachException() + + config.loadConfigs(exclude_sections_list = (config.APPLICATION_SECTION,)) + + ### + + def initBus(self) : + bus_type = config.value(config.APPLICATION_SECTION, "bus_type") + service_name = config.value(config.APPLICATION_SECTION, "service_name") + + try : + config.setValue(config.RUNTIME_SECTION, "bus_name", dbus.service.BusName(service_name, + ( dbus.SystemBus() if bus_type == const.BUS_TYPE_SYSTEM else dbus.SessionBus() ))) + except : + logger.error("Could not connect to D-Bus \"%s\"" % (bus_type)) + logger.attachException() + raise + + logger.verbose("Connected to D-Bus \"%s\" as \"%s\"" % (bus_type, service_name)) + + ### + + def initServices(self) : + for service_name in self._services_dict.keys() : + if config.value(service_name, "enabled") : + try : + self._services_dict[service_name]["service"] = self._services_dict[service_name]["service_class"]() + self._services_dict[service_name]["service"].initService() + except : + logger.error("Cannot initialize service \"%s\"" % (service_name)) + logger.attachException() + + def closeServices(self) : + for service_name in self._services_dict.keys() : + if self._services_dict[service_name]["service"] != None : + try : + self._services_dict[service_name]["service"].closeService() + del self._services_dict[service_name]["service"] + except : + logger.error("Cannot close service \"%s\"" % (service_name)) + logger.attachException() + self._services_dict[service_name]["service"] = None + diff --git a/settingsd/startup.py b/settingsd/startup.py deleted file mode 100644 index fced2ebec44503711dc61258d63bc65745ad86d7..0000000000000000000000000000000000000000 --- a/settingsd/startup.py +++ /dev/null @@ -1,114 +0,0 @@ -# -*- coding: utf-8 -*- - -import sys -import os -import signal -import syslog - -import const -import config -import logger -import application -import daemon - - -##### Public classes ##### -class Startup(object) : - def __init__(self, log_level, use_syslog_flag, bus_type, daemon_mode_flag) : - object.__init__(self) - - ##### - - self._log_level = log_level - self._use_syslog_flag = use_syslog_flag - self._bus_type = bus_type - self._daemon_mode_flag = daemon_mode_flag - - ##### - - self._app = application.Application() - - - ### Public ### - - def run(self) : - self.prepare() - if self._daemon_mode_flag : - self.runDaemon() - else : - self.runInteractive() - - - ### Private ### - - def prepare(self) : - if self._use_syslog_flag == None : - if self._daemon_mode_flag : - syslog.openlog(const.MY_NAME, syslog.LOG_PID, syslog.LOG_DAEMON) - config.setValue(config.RUNTIME_SECTION, "use_syslog", True) - else : - syslog.openlog(const.MY_NAME, syslog.LOG_PID, ( syslog.LOG_DAEMON if self._daemon_mode_flag else syslog.LOG_USER )) - config.setValue(config.RUNTIME_SECTION, "use_syslog", True) - - try : - self._app.loadApplicationConfigs() - except : - logger.error("Initialization error") - logger.attachException() - raise - - if self._bus_type != None : - config.setValue(config.APPLICATION_SECTION, "bus_type", self._bus_type) - - if self._log_level != None : - config.setValue(config.APPLICATION_SECTION, "log_level", self._log_level) - - config.setValue(config.RUNTIME_SECTION, "application", self._app) - config.setValue(config.RUNTIME_SECTION, "startup", self) - - ### - - def runInteractive(self) : - try : - self._app.loadModules() - self._app.loadServicesConfigs() - self._app.initBus() - self._app.initServices() - logger.info("Initialized") - except : - logger.error("Initialization error") - logger.attachException() - raise - - try : - signal.signal(signal.SIGTERM, self.quit) - signal.signal(signal.SIGQUIT, self.quit) - except : - logger.error("signal() error") - logger.attachException() - - try : - self._app.runLoop() - except (SystemExit, KeyboardInterrupt) : - self.quit() - except : - logger.error("Runtime error, trying to close services") - logger.attachException() - self.quit() - raise - - def runDaemon(self) : - work_dir_path = ( "/" if os.getuid() == 0 else None ) - umask = ( 077 if os.getuid() == 0 else None ) - daemon.startDaemon(self.runInteractive, work_dir_path, umask) - - ### - - def quit(self, signum = None, frame = None) : - if signum != None : - logger.info("Recieved signal %d, closing..." % (signum)) - - self._app.closeServices() - self._app.quitLoop() - logger.info("Closed") -