mirror of
https://github.com/OpenMTC/OpenMTC.git
synced 2025-02-25 02:16:19 +00:00
166 lines
3.8 KiB
Python
166 lines
3.8 KiB
Python
'''
|
|
Created on 02.02.2012
|
|
|
|
@author: kca
|
|
'''
|
|
|
|
from time import sleep
|
|
from abc import ABCMeta, abstractproperty, abstractmethod
|
|
from futile import Base
|
|
from futile.path import Path
|
|
from . import check_call, STDOUT
|
|
|
|
class DaemonController(Base):
|
|
__metaclass__ = ABCMeta
|
|
|
|
def __init__(self, sleep = 5, stop_sleep = 3, *args, **kw):
|
|
super(DaemonController, self).__init__(*args, **kw)
|
|
self.__sleep = int(sleep)
|
|
self.__stop_sleep = int(stop_sleep)
|
|
|
|
@abstractproperty
|
|
def is_running(self):
|
|
raise NotImplementedError()
|
|
|
|
def start(self):
|
|
self._start()
|
|
sleep(self.__sleep)
|
|
|
|
@abstractmethod
|
|
def _start(self):
|
|
raise NotImplementedError()
|
|
|
|
def stop(self):
|
|
self._stop()
|
|
sleep(self.__stop_sleep)
|
|
|
|
@abstractmethod
|
|
def _stop(self):
|
|
raise NotImplementedError()
|
|
|
|
def __enter__(self):
|
|
self.start()
|
|
return self
|
|
|
|
def __exit__(self, exc_type, exc_val, exc_tb):
|
|
self.stop()
|
|
|
|
class DummyController(DaemonController):
|
|
def __init__(self, sleep = 0, stop_sleep = 0, *args, **kw):
|
|
super(DummyController).__init__(sleep = sleep, stop_sleep = stop_sleep, *args, **kw)
|
|
|
|
def _start(self):
|
|
pass
|
|
_stop = _start
|
|
|
|
@property
|
|
def is_running(self):
|
|
return False
|
|
|
|
import os
|
|
import errno
|
|
|
|
class CheckPIDFileController(DaemonController):
|
|
def __init__(self, pidfile, *args, **kw):
|
|
super(CheckPIDFileController, self).__init__(*args, **kw)
|
|
self.__pidfile = Path(pidfile)
|
|
|
|
@property
|
|
def pidfile(self):
|
|
return self.__pidfile
|
|
|
|
@property
|
|
def is_running(self):
|
|
if not self.pidfile.exists():
|
|
return False
|
|
|
|
if not self.pidfile.isfile():
|
|
raise Exception("pidfile '%s' is not a file" % (self.pidfile, ))
|
|
|
|
try:
|
|
pid = int(self.__pidfile.open().readline(16))
|
|
except:
|
|
self.logger.exception("Error reading pidfile %s" % (self.pidfile))
|
|
raise
|
|
|
|
try:
|
|
os.kill(pid, 0)
|
|
return True
|
|
except OSError, e:
|
|
if e.errno == errno.ESRCH:
|
|
return False
|
|
raise
|
|
|
|
class StartStopDaemonController(CheckPIDFileController):
|
|
def __init__(self, executable, fork = False, workingdir = None, pidfile = None, makepidfile = False, daemonargs = None, ssd = "/sbin/start-stop-daemon", ldpath = None, outfile = "/dev/null", *args, **kw):
|
|
if not pidfile:
|
|
pidfile = "/tmp/" + executable.replace("/", "_") + ".pid"
|
|
super(StartStopDaemonController, self).__init__(pidfile = pidfile, *args, **kw)
|
|
|
|
self.__executable = unicode(executable)
|
|
self.__workingdir = workingdir and unicode(workingdir) or None
|
|
|
|
if ldpath is not None:
|
|
if not isinstance(ldpath, (list, set, tuple, frozenset)):
|
|
ldpath = [ ldpath ]
|
|
ldpath = tuple(set(ldpath))
|
|
self.__ldpath = ldpath
|
|
|
|
self.__makepidfile = makepidfile
|
|
self.__daemonargs = daemonargs
|
|
self.__fork = fork
|
|
self.__ssd = ssd
|
|
self.__outfile = outfile
|
|
|
|
def get_daemonargs(self):
|
|
return self.__daemonargs
|
|
def set_daemonargs(self, da):
|
|
self.__daemonargs = da
|
|
daemonargs = property(get_daemonargs, set_daemonargs)
|
|
|
|
def __make_cmd(self, cmd, test):
|
|
cmd = [ self.__ssd, cmd, '-x', self.__executable, '-p', self.pidfile, '-o' ]
|
|
|
|
if self.__workingdir:
|
|
cmd += [ '-d', self.__workingdir ]
|
|
|
|
if test:
|
|
cmd.append('-t')
|
|
|
|
env = None
|
|
if self.__ldpath:
|
|
env = dict(LD_LIBRARY_PATH = ':'.join(self.__ldpath))
|
|
|
|
return cmd, env
|
|
|
|
def __check_cmd(self, cmd, env):
|
|
self.logger.debug("ssd env: " + str(env))
|
|
|
|
outfile = self.__outfile
|
|
if outfile:
|
|
outfile = Path(outfile).open("a")
|
|
|
|
try:
|
|
check_call(cmd, stdout = outfile, stderr = STDOUT, close_fds = True, cwd = self.__workingdir, env = env)
|
|
finally:
|
|
if outfile is not None:
|
|
outfile.close()
|
|
|
|
def _start(self):
|
|
cmd, env = self.__make_cmd("-S", False)
|
|
if self.__makepidfile:
|
|
cmd.append('-m')
|
|
|
|
if self.__fork:
|
|
cmd.append('-b')
|
|
|
|
if self.__daemonargs:
|
|
cmd += [ '--' ] + list(self.__daemonargs)
|
|
|
|
self.__check_cmd(cmd, env)
|
|
|
|
def _stop(self):
|
|
cmd, env = self.__make_cmd("-K", False)
|
|
self.__check_cmd(cmd, env)
|
|
|