import logging import os import subprocess import warnings logger = logging.getLogger() class RADVDSvc(object): svc_name = 'radvd' def __init__(self): self.name = self.svc_name self.is_systemd = False self._get_manager() def _get_manager(self): chkpaths = ('/run/systemd/system', '/dev/.run/systemd', '/dev/.systemd') for _ in chkpaths: if os.path.exists(_): self.is_systemd = True break return(None) def restart(self): if self.is_systemd: cmd = ['systemd', 'restart', self.name] else: # Systemd haters, if you don't understand the benefits of unified service management across all linux # distros, you've obviously never done wide-platform management or scripting. # Let this else block be a learning experience for you. cmd = None has_pkill = False for p in os.environ.get('PATH', '/usr/bin').split(':'): fpath = os.path.abspath(os.path.expanduser(p)) bins = os.listdir(fpath) if 'pkill' in bins: has_pkill = True if 'service' in bins: # CentOS/RHEL pre-7.x cmd = ['service', self.name, 'restart'] break elif 'initctl' in bins: # older Ubuntu and other Upstart distros cmd = ['initctl', 'restart', self.name] break elif 'rc-service' in bins: # OpenRC cmd = ['rc-service', self.name, 'restart'] break # That wasn't even all of them. if not cmd and has_pkill: # last-ditch effort. cmd = ['pkill', '-HUP', self.name] if not cmd: logger.error('Could not find which service manager this system is using.') raise RuntimeError('Could not determine service manager') cmd_exec = subprocess.run(cmd, stdin = subprocess.PIPE, stdout = subprocess.PIPE) if cmd_exec.returncode != 0: logger.warning('Could not successfully restart {0}; returned status {1}'.format(self.name, cmd_exec.returncode)) for i in ('stdout', 'stderr'): s = getattr(cmd_exec, i).decode('utf-8') if s.strip() != '': logger.warning('{0}: {1}'.format(i.upper(), s)) warnings.warn('Service did not restart successfully') return(None) class RADVDConf(object): path = '/etc/radvd.conf' tpl = ('interface {iface} {{\n' '\tAdvSendAdvert on;\n' # '\tAdvLinkMTU 1280;\n' # Is it 1480 or 1280? Arch wiki says 1480, but everything else (older) says 1280. '\tAdvLinkMTU 1480;\n' '\tMinRtrAdvInterval 60;\n' '\tMaxRtrAdvInterval 600;\n' '\tAdvDefaultLifetime 9000;\n' '{prefix}' 'route ::/0 {{\n' '\t\tAdvRouteLifetime infinity;' '}};\n' '{rdnss}' '}};\n\n') tpl_prefix = ('\tprefix {subnet} {{\n' '\t\tAdvOnLink on;' '\t\tAdvAutonomous on;' '\t\tAdvRouterAddr off;\n' '}};\n') tpl_rdnss = ('\tRDNSS {client_ip} {{\n' '\t\tAdvRDNSSOpen on;\n' '\t\tAdvRDNSSPreference 2;\n' '}};\n') def __init__(self, cfg = None): if not cfg: self.cfg = self.path else: self.cfg = os.path.abspath(os.path.expanduser(cfg)) self.cfgStr = None def generate(self, assign_objs): self.cfgStr = '' for assign_obj in assign_objs: prefix = self.tpl_prefix.format(subnet = str(assign_obj.net)) if assign_obj.dns: dns = self.tpl_rdnss.format(client_ip = assign_obj.iface_ip.str) else: dns = '' self.cfgStr += self.tpl.format(prefix = prefix, rdnss = dns) class RADVD(object): def __init__(self): self.svc = RADVDSvc() self.conf = RADVDConf(cfg = '/etc/radvd.conf')