import subprocess import logging import shutil logger = logging.getLogger(__name__) class ServiceManager: def __init__(self, service_name='openvpn'): self.service_name = service_name self.init_system = self._detect_init_system() def _detect_init_system(self): """Detect if systemd or openrc is used.""" if shutil.which('systemctl'): return 'systemd' elif shutil.which('rc-service'): return 'openrc' else: return 'unknown' def _run_cmd(self, cmd): try: subprocess.run(cmd, check=True, capture_output=True, text=True) return True, "Success" except subprocess.CalledProcessError as e: return False, e.stderr.strip() except Exception as e: return False, str(e) def start(self): if self.init_system == 'systemd': return self._run_cmd(['sudo', 'systemctl', 'start', self.service_name]) elif self.init_system == 'openrc': return self._run_cmd(['sudo', 'rc-service', self.service_name, 'start']) return False, "Unknown init system" def stop(self): if self.init_system == 'systemd': return self._run_cmd(['sudo', 'systemctl', 'stop', self.service_name]) elif self.init_system == 'openrc': return self._run_cmd(['sudo', 'rc-service', self.service_name, 'stop']) return False, "Unknown init system" def restart(self): if self.init_system == 'systemd': return self._run_cmd(['sudo', 'systemctl', 'restart', self.service_name]) elif self.init_system == 'openrc': return self._run_cmd(['sudo', 'rc-service', self.service_name, 'restart']) return False, "Unknown init system" def get_status(self): """Return 'active', 'inactive', or 'error'""" if self.init_system == 'systemd': # systemctl is-active returns 0 if active, non-zero otherwise try: subprocess.run(['systemctl', 'is-active', self.service_name], check=True, capture_output=True) return 'active' except subprocess.CalledProcessError: return 'inactive' elif self.init_system == 'openrc': try: res = subprocess.run(['rc-service', self.service_name, 'status'], capture_output=True, text=True) if 'started' in res.stdout or 'running' in res.stdout: return 'active' return 'inactive' except: return 'error' return 'unknown'