Ideas / TODO:
-* Revisar interacción entre firewall y nat que ambos usan iptables. Es probable
- que al manipular reglas por número de índice se complique todo porque tengo
- indices separados por tipo de regla, entonces si pongo borrar la 2 tal vez es
- la 13 en vez de la dos porque hay otras 11 reglas de otros sub-servicios que
- usan iptables. Tal vez la solución simple es hacer algo como:
- router firewall add [regla]
- router nat masq add [masq]
- router nat forward add [port]
- router nat snat add [snat]
- (u organizándolo de otra forma pero que tengan todos un root en común)
-
* Agregar soporte de opciones de línea de comando/archivo de conf para:
* Dry run.
* Seleccionar servicios a usar.
* Paths.
* SubHandlers:
- * ComposeDictSubHandler con soporte de dirty/del/add (para ip y DNS).
- * Agregar SimpleDictSubHandler? (que no use una clase, que use un dict
- de strings directamente, para Proxy Users por ej.). Ídem List.
* Agregar SetSubHandler? (para Proxy Hosts)
* Agregar logging.
* Agregar validación con formencode.
-* Ver como manejar la información sobre si un servicio está andando o no. Si se
- agrega una acción 'status' para ver el estado y si ese estado se saca de posta
- de /proc o si es un estado interno y se asume que los servicios no se caen (no
- creo que sea una buena idea esto último). Además habría que ver cuando arranca
- el pymin, si se inician servicios automáticamente o no y si la info de qué
- servicios iniciar o no es persistente y si puede configurarla el usuario.
+* Hacer que el estado sobre si un servicio está andando o no sea más confiable
+ que un simple flag interno (en caso de ver que realmente esté corriendo,
+ probablemente sea una buena idea que haya un flag que indique si hay que
+ levantarlo en el inicio).
* No usar comandos con templates, porque después si no hay que ejecutarlos con
un shell (porque el template devuelve un string todo grande) y hay que andar
teniendo cuidado de escapar las cosas (y hay riesgos de seguridad de shell
injection).
-Estas cosas quedan sujetas a necesitada y a definición del protocolo.
-Para mí lo ideal es que el protocolo de red sea igual que la consola del
-usuario, porque después de todo no va a ser más que eso, mandar comanditos.
-
-Por otro lado, el cliente de consola, por que no es el cliente web pero
-accedido via ssh usando un navegador de texto como w3m???
-
config_path = join(base_path, 'config')
class Root(Handler):
- ip = IpHandler(
- pickle_dir = join(pickle_path, 'ip'),
- config_dir = join(config_path, 'ip'))
firewall = FirewallHandler(
pickle_dir = join(pickle_path, 'firewall'),
config_dir = '/tmp')
- dhcp = DhcpHandler(
- pickle_dir = join(pickle_path, 'dhcp'),
- config_dir = '/etc')
+ nat = NatHandler(pickle_dir = join(pickle_path, 'nat'))
+
+ ppp = PppHandler(
+ pickle_dir = join(pickle_path, 'ppp'),
+ config_dir = {
+ 'pap-secrets': '/etc/ppp',
+ 'chap-secrets': '/etc/ppp',
+ 'options.X': '/etc/ppp',
+ 'nameX': '/etc/ppp/peers',
+ })
+
+ ip = IpHandler(
+ pickle_dir = join(pickle_path, 'ip'),
+ config_dir = join(config_path, 'ip'))
dns = DnsHandler(
pickle_dir = join(pickle_path, 'dns'),
'zoneX.zone': '/var/lib/named',
})
- nat = NatHandler(pickle_dir = join(pickle_path, 'nat'))
+ dhcp = DhcpHandler(
+ pickle_dir = join(pickle_path, 'dhcp'),
+ config_dir = '/etc')
proxy = ProxyHandler(
pickle_dir = join(pickle_path, 'proxy'),
config_dir = join(config_path, 'vrrp'),
pid_dir = '/var/run')
- ppp = PppHandler(
- pickle_dir = join(pickle_path, 'ppp'),
- config_dir = {
- 'pap-secrets': '/etc/ppp',
- 'chap-secrets': '/etc/ppp',
- 'options.X': '/etc/ppp',
- 'nameX': '/etc/ppp/peers',
- })
-
bind_addr = \
(
'', # Bind IP ('' is ANY)
raise HelpNotFoundError(command)
return handler.handler_help
+ def handle_timer(self):
+ r"""handle_timer() -> None :: Do periodic tasks.
+
+ By default we do nothing but calling handle_timer() on subhandlers.
+ """
+ for a in dir(self):
+ if a == 'parent': continue # Skip parents in SubHandlers
+ h = getattr(self, a)
+ if isinstance(h, Handler):
+ h.handle_timer()
+
def parse_command(command):
r"""parse_command(command) -> (args, kwargs) :: Parse a command.
"""
import select
+import errno
+import signal
from select import POLLIN, POLLPRI, POLLERR
__ALL__ = ('EventLoop', 'LoopInterruptedError')
r"str(obj) -> String representation."
return 'Loop interrupted: %s' % self.select_error
+# Flag to know if a timer was expired
+timeout = False
+
+# Alarm Signal handler
+def alarm_handler(signum, stack_frame):
+ global timeout
+ timeout = True
+
class EventLoop:
- r"""EventLoop(file[, handler]) -> EventLoop instance
+ r"""EventLoop(file[, timer[, handler[, timer_handler]]]) -> EventLoop.
This class implements a simple event loop based on select module.
It "listens" to activity a single 'file' object (a file, a pipe,
function (or the handle() method if you prefer subclassing) every
time the file is ready for reading (or has an error).
+ If a 'timer' is supplied, then the timer_handler() function object
+ (or the handle_timer() method) is called every 'timer' seconds.
+
This is a really simple example of usage using a hanlder callable:
- >>> import os
+ >>> import os
>>> def handle(event_loop):
data = os.read(event_loop.fileno, 100)
os.write(1, 'Received message: %r\n' % data)
>>> self.stop()
>>> else:
>>> os.write(1, 'Received message: %r\n' % data)
- >>> p = Test(0)
+ >>> def handle_timer(self):
+ >>> print time.strftime('%c')
+ >>> p = Test(0, timer=5)
>>> p.loop()
This example loops until the user enters a single "q", when stop()
is called and the event loop is exited.
"""
- def __init__(self, file, handler=None):
+ def __init__(self, file, handler=None, timer=None, timer_handler=None):
r"""Initialize the EventLoop object.
See EventLoop class documentation for more info.
self.poll = select.poll()
self._stop = False
self.__register(file)
+ self.timer = timer
self.handler = handler
+ self.timer_handler = timer_handler
def __register(self, file):
r"__register(file) -> None :: Register a new file for polling."
Wait for events and handle then when they arrive. If once is True,
then only 1 event is processed and then this method returns.
"""
+ # Flag modified by the signal handler
+ global timeout
+ # If we use a timer, we set up the signal
+ if self.timer is not None:
+ signal.signal(signal.SIGALRM, alarm_handler)
+ signal.alarm(self.timer)
while True:
try:
res = self.poll.poll()
except select.error, e:
- raise LoopInterruptedError(e)
- if self.handler is not None:
- self.handler(self)
+ # The error is not an interrupt caused by the alarm, then raise
+ if e.args[0] != errno.EINTR or not timeout:
+ raise LoopInterruptedError(e)
+ # There was a timeout, so execute the timer handler
+ if timeout:
+ timeout = False
+ self.handle_timer()
+ signal.alarm(self.timer)
+ # Not a timeout, execute the regular handler
else:
self.handle()
+ # Look if we have to stop
if self._stop or once:
self._stop = False
break
def handle(self):
r"handle() -> None :: Abstract method to be overriden to handle events."
- raise NotImplementedError
+ self.handler(self)
+
+ def handle_timer(self):
+ r"handle() -> None :: Abstract method to be overriden to handle events."
+ self.timer_handler(self)
if __name__ == '__main__':
import os
+ import time
def handle(event_loop):
data = os.read(event_loop.fileno, 100)
self.stop()
else:
os.write(1, 'Received message: %r\n' % data)
+ def handle_timer(self):
+ print time.strftime('%c')
- p = Test(0)
+ p = Test(0, timer=5)
os.write(1, 'Say a lot of things, then press write just "q" to stop: ')
p.loop()
>>> PyminDaemon(Root(), ('', 9999)).run()
"""
- def __init__(self, root, bind_addr=('', 9999)):
+ def __init__(self, root, bind_addr=('', 9999), timer=1):
r"""Initialize the PyminDaemon object.
See PyminDaemon class documentation for more info.
sock.setsockopt(socket.SOL_SOCKET, socket.SO_REUSEADDR, 1)
sock.bind(bind_addr)
# Create EventLoop
- eventloop.EventLoop.__init__(self, sock)
+ eventloop.EventLoop.__init__(self, sock, timer=timer)
# Create Dispatcher
#TODO root.pymin = PyminHandler()
self.dispatcher = dispatcher.Dispatcher(root)
response += u'%d\n%s' % (len(result), result)
self.file.sendto(response.encode('utf-8'), addr)
+ def handle_timer(self):
+ r"handle_timer() -> None :: Call handle_timer() on handlers."
+ self.dispatcher.root.handle_timer()
+
def run(self):
r"run() -> None :: Run the event loop (shortcut to loop())"
try:
self._persistent_dir = pickle_dir
self._config_writer_cfg_dir = config_dir
self._config_build_templates()
- self._restore()
+ InitdHandler.__init__(self)
self.host = HostHandler(self)
def _get_config_vars(self, config_file):
self._config_writer_cfg_dir = config_dir
self._update = False
self._config_build_templates()
- self._restore()
- # FIXME self._update = True
- #if not self._restore():
- #r = self._restore()
- #print r
- #if not r:
- # self._update = True
+ InitdHandler.__init__(self)
self.host = HostHandler(self)
self.zone = ZoneHandler(self)
self.mx = MailExchangeHandler(self)
delete_zones = list()
for a_zone in self.zones.values():
if a_zone._update or a_zone._add:
- if not a_zone._add:
+ if not a_zone._add and self._service_running:
call(('rndc', 'freeze', a_zone.name))
vars = dict(
zone = a_zone,
self._write_single_config('zoneX.zone',
self._zone_filename(a_zone), vars)
a_zone._update = False
- if not a_zone._add:
+ if not a_zone._add and self._service_running:
call(('rndc', 'thaw', a_zone.name))
else :
self._update = True
if self._update:
self._write_single_config('named.conf')
self._update = False
- self.reload()
+ return False # Do reload
+ return True # we don't need to reload
if __name__ == '__main__':
handler_help = u"Manage firewall service"
- _persistent_attrs = 'rules'
+ _persistent_attrs = ['rules']
_restorable_defaults = dict(rules=list())
self._service_restart = self._service_start
self._service_reload = self._service_start
self._config_build_templates()
- self._restore()
+ ServiceHandler.__init__(self)
self.rule = RuleHandler(self)
def _get_config_vars(self, config_file):
self._config_writer_cfg_dir = config_dir
self._config_build_templates()
self._restore()
+ self._write_config()
self.addr = AddressHandler(self)
self.route = RouteHandler(self)
self.dev = DeviceHandler(self)
), shell=True)
+ def handle_timer(self):
+ self.refresh_devices()
+
+
+ def refresh_devices(self):
+ devices = get_network_devices()
+ #add not registered devices
+ for k,v in devices.items():
+ if k not in self.devices:
+ self.devices[k] = Device(k,v)
+ #delete dead devices
+ for k in self.devices.keys():
+ if k not in devices:
+ del self.devices[k]
+
+
+
if __name__ == '__main__':
- ip = IpHandler()
+ ip = IpHanlder()
print '----------------------'
ip.hop.add('201.21.32.53','eth0')
ip.hop.add('205.65.65.25','eth1')
from pymin.dispatcher import Handler, handler, HandlerError
from pymin.services.util import Restorable, ConfigWriter, RestartHandler, \
ReloadHandler, TransactionalHandler, \
- ListSubHandler, call
+ ServiceHandler, ListSubHandler, call
__ALL__ = ('NatHandler',)
_cont_subhandler_attr = 'masqs'
_cont_subhandler_class = Masq
-class NatHandler(Restorable, ConfigWriter, RestartHandler, ReloadHandler,
- TransactionalHandler):
+class NatHandler(Restorable, ConfigWriter, ReloadHandler, ServiceHandler,
+ TransactionalHandler):
r"""NatHandler([pickle_dir[, config_dir]]) -> NatHandler instance.
Handles NAT commands using iptables.
masqs=list(),
)
- @handler(u'Start the service.')
- def start(self):
+ def _service_start(self):
+ call(('iptables', '-t', 'nat', '-F'))
for (index, port) in enumerate(self.ports):
call(['iptables'] + port.as_call_list(index+1))
for (index, snat) in enumerate(self.snats):
for (index, masq) in enumerate(self.masqs):
call(['iptables'] + masq.as_call_list(index+1))
- @handler(u'Stop the service.')
- def stop(self):
+ def _service_stop(self):
call(('iptables', '-t', 'nat', '-F'))
+ _service_restart = _service_start
+
def __init__(self, pickle_dir='.'):
r"Initialize the object, see class documentation for details."
self._persistent_dir = pickle_dir
- self._restore()
+ ServiceHandler.__init__(self)
self.forward = PortForwardHandler(self)
self.snat = SNatHandler(self)
self.masq = MasqHandler(self)
# vim: set encoding=utf-8 et sw=4 sts=4 :
+import os
from os import path
+from signal import SIGTERM
from pymin.seqtools import Sequence
from pymin.dispatcher import Handler, handler, HandlerError
-from pymin.services.util import Restorable, ConfigWriter \
- ,TransactionalHandler, DictSubHandler, call
+from pymin.services.util import Restorable, ConfigWriter, ReloadHandler, \
+ TransactionalHandler, DictSubHandler, call
__ALL__ = ('PppHandler',)
self.username = username
self.password = password
self.type = type
+ self._running = False
if type == 'OE':
if not 'device' in kw:
raise ConnectionError('Bad arguments for type=OE')
_cont_subhandler_attr = 'conns'
_cont_subhandler_class = Connection
-class PppHandler(Restorable, ConfigWriter, TransactionalHandler):
+class PppHandler(Restorable, ConfigWriter, ReloadHandler, TransactionalHandler):
handler_help = u"Manage ppp service"
- _persistent_attrs = ('conns')
+ _persistent_attrs = ['conns']
_restorable_defaults = dict(
conns = dict(),
self._config_writer_cfg_dir = config_dir
self._config_build_templates()
self._restore()
+ for conn in self.conns.values():
+ if conn._running:
+ conn._running = False
+ self.start(conn.name)
self.conn = ConnectionHandler(self)
- @handler('Starts the service')
- def start(self, name):
- if name in self.conns:
- call(['pppd','call', name],stdout=None, stderr=None)
- #print ('pon', name)
- else:
- raise ConnectionNotFoundError(name)
-
- @handler('Stops the service')
- def stop(self, name):
+ @handler(u'Start one or all the connections.')
+ def start(self, name=None):
+ names = [name]
+ if name is None:
+ names = self.conns.keys()
+ for name in names:
+ if name in self.conns:
+ if not self.conns[name]._running:
+ call(('pppd', 'call', name))
+ self.conns[name]._running = True
+ self._dump_attr('conns')
+ else:
+ raise ConnectionNotFoundError(name)
+
+ @handler(u'Stop one or all the connections.')
+ def stop(self, name=None):
+ names = [name]
+ if name is None:
+ names = self.conns.keys()
+ for name in names:
+ if name in self.conns:
+ if self.conns[name]._running:
+ call(('poff', name))
+ if path.exists('/var/run/ppp-' + name + '.pid'):
+ pid = file('/var/run/ppp-' + name + '.pid').readline()
+ try:
+ os.kill(int(pid.strip()), SIGTERM)
+ except OSError:
+ pass # XXX report error?
+ self.conns[name]._running = False
+ self._dump_attr('conns')
+ else:
+ raise ConnectionNotFoundError(name)
+
+ @handler(u'Restart one or all the connections (even disconnected ones).')
+ def restart(self, name=None):
+ names = [name]
+ if name is None:
+ names = self.conns.keys()
+ for name in names:
+ self.stop(name)
+ self.start(name)
+
+ @handler(u'Restart only one or all the already running connections.')
+ def reload(self, name=None):
+ r"reload() -> None :: Reload the configuration of the service."
+ names = [name]
+ if name is None:
+ names = self.conns.keys()
+ for name in names:
+ if self.conns[name]._running:
+ self.stop(name)
+ self.start(name)
+
+ @handler(u'Tell if the service is running.')
+ def running(self, name=None):
+ r"reload() -> None :: Reload the configuration of the service."
+ if name is None:
+ return [c.name for c in self.conns.values() if c._running]
if name in self.conns:
- if path.exists('/var/run/ppp-' + name + '.pid'):
- pid = file('/var/run/ppp-' + name + '.pid').readline().strip()
- call(['kill',pid],stdout=None, stderr=None)
- #print ('poff', name)
+ return int(self.conns[name]._running)
else:
raise ConnectionNotFoundError(name)
- @handler('Reloads the service')
- def reload(self):
- for conn in self.conns.values():
- self.stop(conn.name)
- self.start(conn.name)
-
def _write_config(self):
r"_write_config() -> None :: Generate all the configuration files."
#guardo los pass que van el pap-secrets
if __name__ == '__main__':
+
p = PppHandler()
p.conn.add('ppp_c','nico','nico',type='PPP',device='tty0')
p.conn.add('pppoe_c','fede','fede',type='OE',device='tty1')
p.commit()
print p.conn.list()
print p.conn.show()
+
self._persistent_dir = pickle_dir
self._config_writer_cfg_dir = config_dir
self._config_build_templates()
- self._restore()
+ InitdHandler.__init__(self)
self.host = HostHandler(self)
self.user = UserHandler(self)
def get_network_devices():
- p = subprocess.Popen(('ip', 'link', 'list'), stdout=subprocess.PIPE,
+ p = subprocess.Popen(('ip', '-o', 'link'), stdout=subprocess.PIPE,
close_fds=True)
string = p.stdout.read()
p.wait()
d = dict()
- i = string.find('eth')
- while i != -1:
- eth = string[i:i+4]
- m = string.find('link/ether', i+4)
- mac = string[ m+11 : m+11+17]
- d[eth] = mac
- i = string.find('eth', m+11+17)
+ devices = string.splitlines()
+ for dev in devices:
+ mac = ''
+ if dev.find('link/ether') != -1:
+ i = dev.find('link/ether')
+ mac = dev[i+11 : i+11+17]
+ i = dev.find(':',2)
+ name = dev[3: i]
+ d[name] = mac
+ elif dev.find('link/ppp') != -1:
+ i = dev.find('link/ppp')
+ mac = '00:00:00:00:00:00'
+ i = dev.find(':',2)
+ name = dev[3 : i]
+ d[name] = mac
return d
def call(command, stdin=subprocess.PIPE, stdout=subprocess.PIPE,
r"_restore() -> bool :: Restore persistent data or create a default."
try:
self._load()
- # TODO tener en cuenta servicios que hay que levantar y los que no
- if hasattr(self, 'commit'): # TODO deberia ser reload y/o algo para comandos
- self.commit()
return True
except IOError:
for (k, v) in self._restorable_defaults.items():
self._dump()
if hasattr(self, '_write_config'):
self._write_config()
- if hasattr(self, 'reload'):
- self.reload()
return False
class ConfigWriter:
self._write_single_config(t)
-class ServiceHandler(Handler):
+class ServiceHandler(Handler, Restorable):
r"""ServiceHandler([start[, stop[, restart[, reload]]]]) -> ServiceHandler.
This is a helper class to inherit from to automatically handle services
reload=reload).items():
if action is not None:
setattr(self, '_service_%s' % name, action)
+ self._persistent_attrs = list(self._persistent_attrs)
+ self._persistent_attrs.append('_service_running')
+ if '_service_running' not in self._restorable_defaults:
+ self._restorable_defaults['_service_running'] = False
+ self._restore()
+ if self._service_running:
+ self._service_running = False
+ self.start()
@handler(u'Start the service.')
def start(self):
r"start() -> None :: Start the service."
- call(self._service_start)
+ if not self._service_running:
+ if callable(self._service_start):
+ self._service_start()
+ else:
+ call(self._service_start)
+ self._service_running = True
+ self._dump_attr('_service_running')
@handler(u'Stop the service.')
def stop(self):
r"stop() -> None :: Stop the service."
- call(self._service_stop)
+ if self._service_running:
+ if callable(self._service_stop):
+ self._service_stop()
+ else:
+ call(self._service_stop)
+ self._service_running = False
+ self._dump_attr('_service_running')
@handler(u'Restart the service.')
def restart(self):
r"restart() -> None :: Restart the service."
- call(self._service_restart)
+ if callable(self._service_restart):
+ self._service_restart()
+ else:
+ call(self._service_restart)
+ self._service_running = True
+ self._dump_attr('_service_running')
@handler(u'Reload the service config (without restarting, if possible).')
def reload(self):
r"reload() -> None :: Reload the configuration of the service."
- call(self._service_reload)
+ if self._service_running:
+ if callable(self._service_reload):
+ self._service_reload()
+ else:
+ call(self._service_reload)
+
+ @handler(u'Tell if the service is running.')
+ def running(self):
+ r"reload() -> None :: Reload the configuration of the service."
+ if self._service_running:
+ return 1
+ else:
+ return 0
class RestartHandler(Handler):
r"""RestartHandler() -> RestartHandler :: Provides generic restart command.
@handler(u'Reload the service config (alias to restart).')
def reload(self):
r"reload() -> None :: Reload the configuration of the service."
- self.restart()
+ if hasattr(self, '_service_running') and self._service_running:
+ self.restart()
-class InitdHandler(Handler):
+class InitdHandler(ServiceHandler):
+ # TODO update docs, declarative style is depracated
r"""InitdHandler([initd_name[, initd_dir]]) -> InitdHandler.
This is a helper class to inherit from to automatically handle services
self._initd_name = initd_name
if initd_dir is not None:
self._initd_dir = initd_dir
-
- @handler(u'Start the service.')
- def start(self):
- r"start() -> None :: Start the service."
- call((path.join(self._initd_dir, self._initd_name), 'start'))
-
- @handler(u'Stop the service.')
- def stop(self):
- r"stop() -> None :: Stop the service."
- call((path.join(self._initd_dir, self._initd_name), 'stop'))
-
- @handler(u'Restart the service.')
- def restart(self):
- r"restart() -> None :: Restart the service."
- call((path.join(self._initd_dir, self._initd_name), 'restart'))
-
- @handler(u'Reload the service config (without restarting, if possible).')
- def reload(self):
- r"reload() -> None :: Reload the configuration of the service."
- call((path.join(self._initd_dir, self._initd_name), 'reload'))
+ actions = dict()
+ for action in ('start', 'stop', 'restart', 'reload'):
+ actions[action] = (path.join(self._initd_dir, self._initd_name),
+ action)
+ ServiceHandler.__init__(self, **actions)
class TransactionalHandler(Handler):
r"""Handle command transactions providing a commit and rollback commands.
r"commit() -> None :: Commit the changes and reload the service."
if hasattr(self, '_dump'):
self._dump()
+ unchanged = False
if hasattr(self, '_write_config'):
- self._write_config()
- if hasattr(self, 'reload'):
+ unchanged = self._write_config()
+ if not unchanged and hasattr(self, 'reload'):
self.reload()
@handler(u'Discard all the uncommited changes.')
if not param in self.params:
raise ParameterNotFoundError(param)
self.params[param] = value
+ if hasattr(self, '_update'):
+ self._update = True
@handler(u'Get a service parameter.')
def get(self, param):
# vim: set encoding=utf-8 et sw=4 sts=4 :
+import os
from os import path
+from signal import SIGTERM
from subprocess import Popen, PIPE
from pymin.seqtools import Sequence
from pymin.dispatcher import Handler, handler, HandlerError
-from pymin.services.util import Restorable, TransactionalHandler, ParametersHandler, call
+from pymin.services.util import Restorable, TransactionalHandler, \
+ ReloadHandler, RestartHandler, \
+ ServiceHandler, ParametersHandler, call
__ALL__ = ('VrrpHandler',)
-class VrrpHandler(Restorable, ParametersHandler, TransactionalHandler):
+class VrrpHandler(Restorable, ParametersHandler, ReloadHandler, RestartHandler,
+ ServiceHandler, TransactionalHandler):
+
handler_help = u"Manage VRRP service"
- _persistent_attrs = 'params'
+ _persistent_attrs = ['params']
_restorable_defaults = dict(
params = dict( ipaddress='192.168.0.1',
),
)
- def __init__(self, pickle_dir='.', config_dir='.', pid_dir='.'):
- self._persistent_dir = pickle_dir
- self._pid_dir = pid_dir
- self._restore()
-
- @handler('Starts the service')
- def start(self):
+ def _service_start(self):
if self.params['prio'] != '':
- call(('/usr/local/bin/vrrpd','-i',self.params['dev'],'-v',self.params['id'],'-p',self.params['prio'],self.params['ipaddress']))
- #print ('vrrpd','-i',self.params['dev'],'-v',self.params['id'],'-p',self.params['prio'],self.params['ipaddress'])
+ call(('vrrp', '-i', self.params['dev'], '-v', self.params['id'],
+ '-p', self.params['prio'], self.params['ipaddress']))
else:
- call(('/usr/local/bin/vrrpd','-i',self.params['dev'],'-v',self.params['id'],self.params['ipaddress']))
- #print ('vrrpd','-i',self.params['dev'],'-v',self.params['id'],self.params['ipaddress'])
-
- @handler('Stop the service')
- def stop(self):
- try :
- pid = 'vrrpd' + '_' + self.params['dev'] + '_' + self.params['id'] + '.pid'
- f = file(path.join(self._pid_dir, pid ), 'r')
- call(('kill',f.read().strip('\n')))
- #print('kill','<',f.read())
- except IOError:
+ call(('vrrp', '-i', self.params['dev'], '-v', self.params['id'], \
+ self.params['ipaddress']))
+
+ def _service_stop(self):
+ try:
+ pid_filename = 'vrrpd_%(dev)s_%(id)s.pid' % self.params
+ pid = file(path.join(self._pid_dir, pid_filename )).read().strip()
+ os.kill(int(pid), SIGTERM)
+ except (IOError, OSError):
+ # TODO log
pass
- @handler('Reloads the service')
- def reload(self):
- self.stop()
- self.start()
+ def __init__(self, pickle_dir='.', config_dir='.', pid_dir='.'):
+ self._persistent_dir = pickle_dir
+ self._pid_dir = pid_dir
+ ServiceHandler.__init__(self)
if __name__ == '__main__':
v = VrrpHandler()
v.set('prio','10')
v.commit()
+