aif-ng/aif/system/services.py

75 lines
2.8 KiB
Python

import logging
import os
import pathlib
import re
##
import aif.utils
_logger = logging.getLogger(__name__)
_svc_suffixes = ('service', 'socket', 'device', 'mount', 'automount', 'swap', 'target',
'path', 'timer', 'slice', 'scope')
_svc_re = re.compile(r'\.({0})$'.format('|'.join(_svc_suffixes)))
class Service(object):
def __init__(self, service_xml):
self.xml = service_xml
self.slice = None
self.unit_file = None
self.dest_file = None
self.name = service_xml.text.strip()
self.enabled = aif.utils.xmlBool(self.xml.attrib.get('status', 'true'))
p = pathlib.Path(self.name)
suffix = p.suffix.lstrip('.')
if suffix in _svc_suffixes:
self.type = suffix
self.name = _svc_re.sub('', self.name)
else:
self.type = 'service'
s = self.name.split('@', 1)
if len(s) > 1:
self.name = s[0]
self.slice = s[1]
self.unit_file = '{0}@.{1}'.format(self.name, self.type)
self.dest_file = '{0}@{1}.{2}'.format(self.name, self.slice, self.type)
else:
self.unit_file = '{0}.{1}'.format(self.name, self.type)
self.dest_file = self.unit_file
if self.slice:
_logger.info('Initialized service: {0}@{1}'.format(self.name, self.slice))
else:
_logger.info('Initialized service: {0}'.format(self.name))
for a in ('name', 'slice', 'type', 'enabled'):
_logger.debug('{0}: {1}'.format(a.title(), getattr(self, a)))
class ServiceDB(object):
def __init__(self, chroot_base, services_xml):
self.xml = services_xml
self.chroot_base = chroot_base
self.systemd_sys = os.path.join(self.chroot_base, 'usr', 'lib', 'systemd', 'system')
self.systemd_host = os.path.join(self.chroot_base, 'etc', 'systemd', 'system')
self.services = []
for service_xml in self.xml.findall('service'):
svc = Service(service_xml)
self.services.append(svc)
def apply(self):
for svc in self.services:
dest_path = os.path.join(self.systemd_host, svc.dest_file)
src_path = os.path.join(self.systemd_sys, svc.unit_file)
if svc.enabled:
if not os.path.isfile(dest_path):
os.symlink(src_path, dest_path)
_logger.info('Created symlink: {0} => {1}'.format(src_path, dest_path))
_logger.debug('{0} enabled'.format(svc.name))
else:
if os.path.exists(dest_path):
os.remove(dest_path)
_logger.info('Removed file/symlink: {0}'.format(dest_path))
_logger.debug('{0} disabled'.format(svc.name))
return(None)