import repository from arizona
[raven.git] / apps / gacks / gacksresource.py
1 import cPickle
2 import fnmatch
3 import os
4 import hashlib
5
6 from ravenlib.ravenconfigparser import RavenConfigParser
7
8 # since we're passing around pickled objects, lets keep track of versions
9 VERSION=1
10
11 CONTINUOUS=1
12 GROUPED=2
13
14 class GacksResource:
15     def __init__(self, name, qty=100, kind=CONTINUOUS):
16         self.name = name
17         self.kind = kind
18         self.resources = []
19         self.subgroups = []
20         self.qty = qty
21         self.handler = None
22
23         self.plcAttribute = None
24         self.plcServer = None
25         self.plcUser = None
26         self.plcPassword = None
27
28     def add_resource(self, name, qty):
29         self.resources.append(GacksResource(name,qty))
30
31     def add_subgroup(self, name, pattern):
32         self.subgroups.append( (name, pattern) )
33
34     def find_subgroup(self, resource):
35         subgroups=[]
36         for (name, pattern) in self.subgroups:
37             if (fnmatch.fnmatch(resource.name, pattern)):
38                 subgroups.append(name)
39         return subgroups
40
41     def get_subgroups_names(self):
42         return [x[0] for x in self.subgroups]
43
44     def get_subgroups_dict(self):
45         if not self.subgroups:
46             return {}
47         if (self.kind != GROUPED):
48             return {}
49
50         subgroups_dict = {}
51
52         for item in self.resources:
53             item_subgroup_names = self.find_subgroup(item)
54             for subgroup_name in item_subgroup_names:
55                 if not (subgroup_name in subgroups_dict):
56                     subgroups_dict[subgroup_name] = []
57                 subgroups_dict[subgroup_name].append(item)
58
59         return subgroups_dict
60
61     def calc_qty(self):
62         if self.kind == GROUPED:
63             self.qty = 0
64             for item in self.resources:
65                 item.calc_qty()
66                 self.qty = self.qty + item.qty
67
68     def inverse_map(self, i):
69         offset = 0
70         for item in self.resources:
71             if (i>=offset) and (i<offset+item.qty):
72                 return (item, offset)
73             offset = offset + item.qty
74         return (None, None)
75
76     def dump(self, indent=0, dump_subgroups=False):
77         if (self.kind==CONTINUOUS):
78             kind = "cont"
79         elif (self.kind==GROUPED):
80             kind = "grouped"
81         else:
82             kind = "unknown"
83
84         print " " * indent, self.name, kind, self.qty
85
86         if self.subgroups:
87             print " " * (indent+4), "subgroups:"
88             for (name, pattern) in self.subgroups:
89                 print " " * (indent+8), name, pattern
90
91         for item in self.resources:
92             item.dump(indent+4)
93
94         if dump_subgroups:
95             self.dump_subgroups(indent+4)
96
97     def dump_subgroups(self, indent=0):
98         sgdict = self.get_subgroups_dict()
99         for name in self.get_subgroups_names():
100             print " " * indent, name
101             for item in sgdict[name]:
102                 print " " * (indent+4), item.name
103
104 class GacksResourceDirectory:
105     def __init__(self, dir=None):
106         self.version = VERSION
107         self.resources = []
108         if dir:
109             self.read_dir(dir)
110
111     def read_dir(self, dir):
112         for fn in os.listdir(dir):
113             pathname = os.path.join(dir, fn)
114             if not os.path.isfile(pathname):
115                 continue
116             if pathname.endswith("~") or pathname.startswith("~"):
117                 continue
118             self.read_config(pathname)
119
120     def read_config(self, fn):
121         parser = RavenConfigParser()
122
123         parser.update_order = True
124         parser.Read(fn, True)
125         parser.update_order = False
126
127         providerName = parser.GetOpt("provider", "name", None)
128         resources = parser.GetOpt("provider", "resources", None)
129
130         if (not providerName) or (not resources):
131             return
132
133         resources = resources.split(",")
134         resources = [x.strip() for x in resources]
135
136         for resource in resources:
137             enabled = parser.GetOptBool(resource, "enabled", "True")
138             if (not enabled):
139                 continue
140
141             kind = parser.GetOpt(resource, "kind", "continuous")
142             if (kind == "grouped"):
143                 kind = GROUPED
144             elif (kind == "continuous"):
145                 kind = CONTINUOUS
146             else:
147                 raise "unknown resource kind: " + resource + " " + kind
148
149             if (kind==CONTINUOUS):
150                 qty = parser.GetOptInt(resource, "qty", 100)
151                 r = GacksResource(providerName + "." + resource, qty, kind)
152             else:
153                 groupsize = parser.GetOptInt(resource, "groupsize", 1)
154                 groupnames_section = parser.GetOpt(resource, "groupnames", None)
155                 if not groupnames_section:
156                     raise "no groupnames tag in grouped resource " + resource
157
158                 r = GacksResource(providerName + "." + resource, kind=kind)
159
160                 groupnames_options = parser.ordered_options.get(groupnames_section, [])
161                 if not groupnames_options:
162                     groupnames_options = parser.options(groupnames_section)
163
164                 if not groupnames_options:
165                     raise "section " + groupnames_section + " is empty"
166
167                 for x in groupnames_options:
168                     r.add_resource(x, parser.GetOptInt(groupnames_section, x, 1))
169
170                 r.calc_qty()
171
172             subgroups_section = parser.GetOpt(resource, "subgroupnames", None)
173             if subgroups_section:
174                 subgroups_options = parser.ordered_options.get(subgroups_section,[])
175                 for x in subgroups_options:
176                     r.add_subgroup(x, parser.GetOpt(subgroups_section, x, "Unknown"))
177
178             handler = parser.GetOpt(resource, "handler", "plc")
179             r.handler = handler
180
181             if (handler=="plc"):
182                 r.plcAttribute = parser.GetOpt(resource, "plc_attribute", None)
183                 r.plcServer = parser.GetOpt(resource, "plc_server", None)
184                 r.plcUser = parser.GetOpt(resource, "plc_user", None)
185                 r.plcPassword = parser.GetOpt(resource, "plc_password", None)
186
187             self.resources.append(r)
188
189     def get_providers(self):
190         providers = []
191         for item in self.resources:
192             provider = ".".join(item.name.split(".")[:-1])
193             if not provider in providers:
194                 providers.append(provider)
195         return providers
196
197     def get_resource_names(self, provider):
198         names = []
199         for item in self.resources:
200             thisProvider = ".".join(item.name.split(".")[:-1])
201             if thisProvider == provider:
202                 names.append(item.name)
203         return names
204
205     def get_resource(self, name):
206         for item in self.resources:
207             if item.name == name:
208                 return item
209         return None
210
211     def dump(self, dump_subgroups=False):
212         print "hash:"
213         print "    ", self.hash()
214
215         print "providers:"
216         for provider in self.get_providers():
217             print "    ", provider
218
219         print "resources:"
220         for item in self.resources:
221             item.dump(indent=4, dump_subgroups=dump_subgroups)
222
223     def pickled(self):
224         if not hasattr(self, "_pickled"):
225             self._pickled = cPickle.dumps(self)
226             self._hash = hashlib.sha1(self._pickled).hexdigest()
227         return self._pickled
228
229     def hash(self):
230         self.pickled() # makes sure self.__hash is computed
231         return self._hash
232
233 def test_handler(resource):
234     from gackshandler_plc import GacksPLCHandler
235
236     handler = GacksPLCHandler(resource)
237     nodes = handler.getNodes()
238
239 def test():
240     rdir = GacksResourceDirectory(dir="./resources.d")
241     rdir.dump(dump_subgroups=True)
242
243     vicci_cores = rdir.get_resource("plc.vicci.cores")
244     test_handler(vicci_cores)
245
246
247 if __name__=="__main__":
248    test()
249
250