1 from ConfigParser import ConfigParser, NoOptionError |
1 from ConfigParser import ConfigParser |
2 import signal |
2 import signal |
3 from functools import partial |
3 from functools import partial |
4 |
4 |
5 from validate import vInteger |
5 from validate import vInteger |
6 from error import ValidateException |
6 from error import NeededOption |
7 |
7 |
8 class Config(ConfigParser): |
8 class MyConfigParser(ConfigParser): |
9 def __init__(self): |
9 def __init__(self): |
10 ConfigParser.__init__(self) |
10 ConfigParser.__init__(self) |
11 self.reloadList=[] |
11 self.reloadList=[] |
12 |
12 |
13 def read(self,files): |
13 def read(self,files): |
14 from offer import getProvider |
14 from offer import getProvider |
15 ConfigParser.read(self, files) |
15 ConfigParser.read(self, files) |
16 for s in self.sections(): |
16 for s in self.sections(): |
17 if s == "main": |
17 if s == "main": |
18 opts=main |
18 main.validate(self.items(s)) |
19 for o in opts: |
|
20 try: |
|
21 opts[o].validate(self.get(s,o),o) |
|
22 except (ValidateException, NoOptionError): |
|
23 if opts[o].must: |
|
24 raise |
|
25 else: |
19 else: |
26 getProvider("tmp", self.get(s,'typ'), self.items(s)) |
20 getProvider("tmp", self.get(s,'typ'), self.items(s)) |
27 |
|
28 |
21 |
29 def reload_(self): |
22 def reload_(self): |
30 for f in self.reloadList: |
23 for f in self.reloadList: |
31 f() |
24 f() |
32 |
25 |
39 self.long=long |
32 self.long=long |
40 self.help = help |
33 self.help = help |
41 self.must = must |
34 self.must = must |
42 self.default = default |
35 self.default = default |
43 |
36 |
|
37 class Config(): |
|
38 def __init__(self, name): |
|
39 self.name = name |
|
40 self.options={ |
|
41 "hostname":Option(lambda x,y:x,long="Hostname under that twisted is running",must=True), |
|
42 "port":Option(partial(vInteger,minv=0),long="Port under that twisted is running",must=True), |
|
43 "dburl":Option(lambda x,y:x,long="Connection URL to database",must=True), |
|
44 } |
|
45 self.read=False |
|
46 |
|
47 |
|
48 def _read(self, cfg, write=False): |
|
49 c = dict(cfg) |
|
50 for o in self.options: |
|
51 option = self.options[o] |
|
52 try: |
|
53 value = option.validate(c[o],o) |
|
54 if write: |
|
55 self.read = True |
|
56 setattr(self,o,value) |
|
57 except KeyError: |
|
58 if option.must: |
|
59 raise NeededOption(self.name, o) |
|
60 elif write and option.default is not None: |
|
61 setattr(self, o, option.default) |
|
62 |
|
63 def validate(self, cfg): |
|
64 self._read(cfg, False) |
|
65 |
|
66 def load(self, cfg): |
|
67 self._read(cfg, True) |
|
68 |
|
69 def same(self, other): |
|
70 for o in self.options: |
|
71 if getattr(self,o) != getattr(other,o): |
|
72 return False |
|
73 else: |
|
74 return True |
|
75 |
44 def readConfig(): |
76 def readConfig(): |
45 config.read(confFiles) |
77 configParser.read(confFiles) |
46 config.reload() |
78 configParser.reload() |
|
79 if not main.read: |
|
80 main.load(configParser.items("main")) |
|
81 else: |
|
82 m = Config("main").load(configParser.items("main")) |
|
83 if not main.same(m): |
|
84 raise Exception("Main options can't be reloaded, you have to restart.") |
47 |
85 |
48 def registerSignal(): |
86 def registerSignal(): |
49 '''register readConfig to SIGUSR2''' |
87 '''register readConfig to SIGUSR2''' |
50 def rC(signal, frame): |
88 def rC(signal, frame): |
51 readConfig() |
89 readConfig() |
52 |
90 |
53 signal.signal(signal.SIGUSR2,rC) |
91 signal.signal(signal.SIGUSR2,rC) |
54 |
92 |
55 config=Config() |
93 configParser = MyConfigParser() |
56 confFiles=["iro.conf", "~/iro.conf","/etc/iro/iro.conf"] |
94 confFiles=["iro.conf", "~/iro.conf","/etc/iro/iro.conf"] |
57 main={"hostname":Option(lambda x,y:x,long="Hostname under that twisted is running",must=True), |
95 |
58 "port":Option(partial(vInteger,minv=0),long="Port under that twisted is running",must=True), |
96 main = Config("main") |
59 } |
|