import logging import subprocess from rest_framework.exceptions import APIException _log = logging.getLogger(__name__) class AMCServiceException(APIException): pass class AMCService: MAPPING_SERVICE = { 'nginx': 'nginx.service', 'elasticsearch': 'elasticsearch.service', 'gunicorn': 'amcgunicorn.service', 'celery': 'amccelery.service', 'celerybeat': 'amccelerybeat.service', 'correlator': 'amccorrelator.service', 'vector': 'amcvector.service', 'postgresql': 'postgresql.service' } def __init__(self, service_name): self.service = service_name try: self.system_service_name = self.MAPPING_SERVICE[service_name] except KeyError: raise AMCServiceException({'status': 'error', 'detail': f'Unable to work with "{service_name}" service'}) def get_status(self): """ Check whether any of the specified units are active (i.e. running). """ command = ['sudo', 'systemctl', 'is-active', f'{self.system_service_name}'] action = 'get status' return self._run_cmd(command, action) def reboot(self): """ Reload service if they support it. If not, stop and then start them instead If the services are not running yet, they will be started """ command = ['sudo', 'systemctl', 'reload-or-restart', f'{self.system_service_name}'] action = 'reboot' return self._run_cmd(command, action) def _run_cmd(self, cmd, action='perform operation'): subproc = subprocess.run(cmd, capture_output=True) if subproc.returncode != 0: # usually 0 is the correct exit code error = subproc.stderr or subproc.stdout _log.error(f"Can't {action} '{self.service}': {error.decode('utf-8')}") raise AMCServiceException({'status': 'error', 'detail': f"Can't {action} '{self.service}': {error.decode('utf-8').strip()}"}) output = subproc.stdout.decode().strip() return output