]> git.llucax.com Git - software/pymin.git/blob - services/ppp/handler.py
Split ppp handler in submodules (refs #2).
[software/pymin.git] / services / ppp / handler.py
1 # vim: set encoding=utf-8 et sw=4 sts=4 :
2
3 import os
4 import subprocess
5 from os import path
6 from signal import SIGTERM
7 import logging ; log = logging.getLogger('pymin.services.ppp')
8
9 from pymin.dispatcher import Handler, handler
10 from pymin.service.util import Restorable, ConfigWriter, ReloadHandler, \
11                                TransactionalHandler, ItemNotFoundError, call
12
13 from conn import ConnectionHandler
14
15 __all__ = ('PppHandler',)
16
17
18 class PppHandler(Restorable, ConfigWriter, ReloadHandler, TransactionalHandler):
19
20     handler_help = u"Manage ppp service"
21
22     _persistent_attrs = ['conns']
23
24     _restorable_defaults = dict(
25         conns  = dict(),
26     )
27
28     _config_writer_files = ('options.X','pap-secrets','chap-secrets','nameX')
29     _config_writer_tpl_dir = path.join(path.dirname(__file__), 'templates')
30
31     def __init__(self, pickle_dir='.', config_dir='.'):
32         r"Initialize Ppphandler object, see class documentation for details."
33         log.debug(u'PppHandler(%r, %r)', pickle_dir, config_dir)
34         self._persistent_dir = pickle_dir
35         self._config_writer_cfg_dir = config_dir
36         self._config_build_templates()
37         self._restore()
38         log.debug(u'PppHandler(): restoring connections...')
39         for conn in self.conns.values():
40             if conn._running:
41                 log.debug(u'PppHandler(): starting connection %r', conn.name)
42                 conn._running = False
43                 self.start(conn.name)
44         self.conn = ConnectionHandler(self)
45
46     @handler(u'Start one or all the connections.')
47     def start(self, name=None):
48         log.debug(u'PppHandler.start(%r)', name)
49         names = [name]
50         if name is None:
51             names = self.conns.keys()
52         for name in names:
53             if name in self.conns:
54                 if not self.conns[name]._running:
55                     log.debug(u'PppHandler.start: starting connection %r', name)
56                     call(('pppd', 'call', name))
57                     self.conns[name]._running = True
58                     self._dump_attr('conns')
59             else:
60                 log.debug(u'PppHandler.start: connection not found')
61                 raise ItemNotFoundError(name)
62
63     @handler(u'Stop one or all the connections.')
64     def stop(self, name=None):
65         log.debug(u'PppHandler.stop(%r)', name)
66         names = [name]
67         names = [name]
68         if name is None:
69             names = self.conns.keys()
70         for name in names:
71             if name in self.conns:
72                 if self.conns[name]._running:
73                     pid_file = '/var/run/ppp-' + name + '.pid'
74                     log.debug(u'PppHandler.stop: getting pid from %r', pid_file)
75                     if path.exists(pid_file):
76                         pid = file(pid_file).readline()
77                         pid = int(pid.strip())
78                         try:
79                             log.debug(u'PppHandler.stop: killing pid %r', pid)
80                             os.kill(pid, SIGTERM)
81                         except OSError, e:
82                             log.debug(u'PppHandler.stop: error killing: %r', e)
83                     else:
84                         log.debug(u'PppHandler.stop: pid file not found')
85                     self.conns[name]._running = False
86                     self._dump_attr('conns')
87                 else:
88                     log.debug(u'PppHandler.stop: connection not running')
89             else:
90                 log.debug(u'PppHandler.stop: connection not found')
91                 raise ItemNotFoundError(name)
92
93     @handler(u'Restart one or all the connections (even disconnected ones).')
94     def restart(self, name=None):
95         log.debug(u'PppHandler.restart(%r)', name)
96         names = [name]
97         if name is None:
98             names = self.conns.keys()
99         for name in names:
100             self.stop(name)
101             self.start(name)
102
103     @handler(u'Restart only one or all the already running connections.')
104     def reload(self, name=None):
105         r"reload() -> None :: Reload the configuration of the service."
106         log.debug(u'PppHandler.reload(%r)', name)
107         names = [name]
108         if name is None:
109             names = self.conns.keys()
110         for name in names:
111             if self.conns[name]._running:
112                 self.stop(name)
113                 self.start(name)
114
115     @handler(u'Tell if the service is running.')
116     def running(self, name=None):
117         r"reload() -> None :: Reload the configuration of the service."
118         log.debug(u'PppHandler.running(%r)', name)
119         if name is None:
120             return [c.name for c in self.conns.values() if c._running]
121         if name in self.conns:
122             return int(self.conns[name]._running)
123         else:
124             log.debug(u'PppHandler.running: connection not found')
125             raise ItemNotFoundError(name)
126
127     def handle_timer(self):
128         log.debug(u'PppHandler.handle_timer()')
129         for c in self.conns.values():
130             log.debug(u'PppHandler.handle_timer: processing connection %r', c)
131             p = subprocess.Popen(('pgrep', '-f', 'pppd call ' + c.name),
132                                     stdout=subprocess.PIPE)
133             pid = p.communicate()[0]
134             if p.returncode == 0 and len(pid) > 0:
135                 log.debug(u'PppHandler.handle_timer: pid present, running')
136                 c._running = True
137             else:
138                 log.debug(u'PppHandler.handle_timer: pid absent, NOT running')
139                 c._running = False
140
141     def _write_config(self):
142         r"_write_config() -> None :: Generate all the configuration files."
143         log.debug(u'PppHandler._write_config()')
144         #guardo los pass que van el pap-secrets
145         vars_pap = dict()
146         for conn in self.conns.values():
147             if conn.type == 'OE' or conn.type == 'PPP':
148                 vars_pap[conn.name] = conn
149         vars = dict(conns=vars_pap)
150         self._write_single_config('pap-secrets','pap-secrets',vars)
151         #guardo los pass que van el chap-secrets
152         vars_chap = dict()
153         for conn in self.conns.values():
154             if conn.type == 'TUNNEL' :
155                 vars_chap[conn.name] = conn
156         vars = dict(conns=vars_chap)
157         self._write_single_config('chap-secrets','chap-secrets',vars)
158         #guard las conns
159         for conn in self.conns.values():
160             vars = dict(conn=conn)
161             self._write_single_config('nameX',conn.name, vars)
162             self._write_single_config('options.X','options.' + conn.name, vars)
163
164
165 if __name__ == '__main__':
166
167     logging.basicConfig(
168         level   = logging.DEBUG,
169         format  = '%(asctime)s %(levelname)-8s %(message)s',
170         datefmt = '%H:%M:%S',
171     )
172
173     p = PppHandler()
174     p.conn.add('ppp_c','nico','nico',type='PPP',device='tty0')
175     p.conn.add('pppoe_c','fede','fede',type='OE',device='tty1')
176     p.conn.add('ppptunnel_c','dominio\luca','luca',type='TUNNEL',server='192.168.0.23')
177     p.commit()
178     print p.conn.list()
179     print p.conn.show()
180