def process(self): dbus_service = DbusServiceHandler() # Stop SSPL service if state is active service_state = dbus_service.get_state('sspl-ll.service') if service_state._state == 'active': logger.warning ("SSPL service should have been stopped," f"before {self.name} interface is invoked") logger.warning("Stopping SSPL service now...") dbus_service.stop('sspl-ll.service') # Remove sspl data shutil.rmtree(DATA_PATH, ignore_errors=True) # Clear log data from log files and delete 'log.gz' files FileStore().truncate(f"/var/log/{PRODUCT_FAMILY}/sspl/", '.log') FileStore().truncate(f"/var/log/{PRODUCT_FAMILY}/iem/", '.log') FileStore().delete( f"/var/log/{PRODUCT_FAMILY}/sspl/", '.log.gz') FileStore().delete( f"/var/log/{PRODUCT_FAMILY}/iem/", '.log.gz')
def process(self): dbus_service = DbusServiceHandler() # Stop SSPL service if state is active service_state = dbus_service.get_state('sspl-ll.service') if service_state._state == 'active': logger.warning ("SSPL service should have been stopped," f"before {self.name} interface is invoked") logger.warning("Stopping SSPL service now...") dbus_service.stop('sspl-ll.service') # Remove sspl data shutil.rmtree(DATA_PATH, ignore_errors=True) # Remove log files Reset.del_files_from_dir('.log', f"/var/log/{PRODUCT_FAMILY}/sspl/") Reset.del_files_from_dir('.log.gz', f"/var/log/{PRODUCT_FAMILY}/sspl/") Reset.del_files_from_dir('.log', f"/var/log/{PRODUCT_FAMILY}/iem/") Reset.del_files_from_dir('.log.gz', f"/var/log/{PRODUCT_FAMILY}/iem/")
class SystemdService(Debug): """Handles service request messages to systemd""" ACTUATOR_NAME = "SystemdService" @staticmethod def name(): """ @return: name of the module.""" return SystemdService.ACTUATOR_NAME def __init__(self): super(SystemdService, self).__init__() # Use d-bus to communicate with systemd # Described at: http://www.freedesktop.org/wiki/Software/systemd/dbus/ # Obtain an instance of d-bus to communicate with systemd self._bus = SystemBus() # Obtain a manager interface to d-bus for communications with systemd systemd = self._bus.get_object('org.freedesktop.systemd1', '/org/freedesktop/systemd1') self._manager = Interface( systemd, dbus_interface='org.freedesktop.systemd1.Manager') # Subscribe to signal changes self._manager.Subscribe() # create service cls obj. self._service = DbusServiceHandler() def perform_request(self, jsonMsg): """Performs the service request""" self._check_debug(jsonMsg) # Parse out the service name and request to perform on it if jsonMsg.get("actuator_request_type").get("service_controller") \ is not None: self._service_name = jsonMsg.get("actuator_request_type").\ get("service_controller").get("service_name") self._service_request = jsonMsg.get("actuator_request_type").\ get("service_controller").get("service_request") else: self._service_name = jsonMsg.get("actuator_request_type").\ get("service_watchdog_controller").get("service_name") self._service_request = jsonMsg.get("actuator_request_type").\ get("service_watchdog_controller").get("service_request") logger.debug("perform_request, service_name: %s, service_request: %s" % \ (self._service_name, self._service_request)) try: # Load the systemd unit for the service systemd_unit = self._manager.LoadUnit(self._service_name) # Get a proxy to systemd for accessing properties of units self._proxy = self._bus.get_object("org.freedesktop.systemd1", \ str(systemd_unit)) # The returned result of the desired action result = {} is_err_response = False if self._service_request in ['restart', 'start']: # Before restart/start the service, check service state. # If it is not active or activating then only process # restart/start request. service_state = self._service.get_state(self._service_name) state = service_state.state if state not in ['active', 'activating']: if self._service_request == "restart": self._service.restart(self._service_name) elif self._service_request == "start": self._service.start(self._service_name) # Ensure we get an "active" state and not "activating" service_state = self._service.get_state(self._service_name) state = service_state.state max_wait = 0 while state != "active": logger.debug( "%s status is activating, needs 'active' " "state after %s request has been processed, retrying" % (self._service_name, self._service_request)) time.sleep(1) max_wait += 1 if max_wait > 20: logger.debug("maximum wait - %s seconds, for " "service restart reached." % max_wait) break service_state = self._service.get_state( self._service_name) state = service_state.state else: is_err_response = True err_msg = ( "Can not process %s request, for %s, as service " "is already in %s state." % (self._service_request, self._service_name, state)) logger.error(err_msg) return (self._service_name, err_msg, is_err_response) elif self._service_request == "stop": self._service.stop(self._service_name) elif self._service_request == "status": # Return the status below service_status = self._service.get_state(self._service_name) # TODO: Use cortx.utils Service class methods for # enable/disable services. elif self._service_request == "enable": service_list = [] service_list.append(self._service_name) # EnableUnitFiles() function takes second argument as boolean. # 'True' will enable a service for runtime only(creates symlink # in /run/.. directory) 'False' will enable a service # persistently (creates symlink in /etc/.. directory) _, dbus_result = self._manager.EnableUnitFiles( service_list, False, True) res = parse_enable_disable_dbus_result(dbus_result) result.update(res) logger.debug("perform_request, result for enable request: " "result: %s" % (result)) elif self._service_request == "disable": service_list = [] service_list.append(self._service_name) # DisableUnitFiles() function takes second argument as boolean. # 'True' will disable a service for runtime only(removes symlink # from /run/.. directory) 'False' will disable a service # persistently(removes symlink from /etc/.. directory) dbus_result = self._manager.DisableUnitFiles( service_list, False) res = parse_enable_disable_dbus_result(dbus_result) result.update(res) logger.debug( "perform_request, result for disable request: %s" % result) else: logger.error("perform_request, Unknown service request - %s " "for service - %s" % (self._service_request, self._service_name)) is_err_response = True return (self._service_name, "Unknown service request", is_err_response) except debus_exceptions.DBusException as error: is_err_response = True logger.exception("DBus Exception: %r" % error) return (self._service_name, str(error), is_err_response) except Exception as ae: logger.exception("SystemD Exception: %r" % ae) is_err_response = True return (self._service_name, str(ae), is_err_response) # Give the unit some time to finish starting/stopping to get final status time.sleep(5) # Get the current status of the process and return it back: service_status = self._service.get_state(self._service_name) pid = service_status.pid state = service_status.state substate = service_status.substate status = self._service.is_enabled(self._service_name) uptime = get_service_uptime(self._service_name) # Parse dbus output to fetch command line path with args. command_line = service_status.command_line_path command_line_path_with_args = [] for field in list(command_line[0][1]): command_line_path_with_args.append(str(field)) result["pid"] = pid result["state"] = state result["substate"] = substate result["status"] = status result["uptime"] = uptime result["command_line_path"] = command_line_path_with_args logger.debug("perform_request, state: %s, substate: %s" % (str(state), str(substate))) return (self._service_name, result, is_err_response)