]> git.ipfire.org Git - people/shoehn/ipfire.org.git/blame - www/webapp/backend/stasy.py
Fix wrong slogan on index page.
[people/shoehn/ipfire.org.git] / www / webapp / backend / stasy.py
CommitLineData
372efc19
MT
1#!/usr/bin/python
2
3import hwdata
4import logging
5import pymongo
6
7from misc import Singleton
8
9DATABASE_HOST = ["irma.ipfire.org", "madeye.ipfire.org"]
10DATABASE_NAME = "stasy"
11
12MEMORY_CONSTRAINTS = (0, 64, 128, 256, 512, 1024, 2048, 4096, 8128, 16384)
13
14class ProfileDict(object):
15 def __init__(self, data):
16 self._data = data
17
18
19class ProfileCPU(ProfileDict):
20 @property
21 def arch(self):
22 return self._data.get("arch")
23
24 @property
25 def vendor(self):
26 return self._data.get("vendor")
27
28 @property
29 def model(self):
30 return self._data.get("model")
31
32 @property
33 def model_string(self):
34 return self._data.get("model_string")
35
36 @property
37 def flags(self):
38 return self._data.get("flags")
39
40 @property
41 def capable_64bit(self):
42 return "lm" in self.flags
43
44 @property
45 def capable_pae(self):
46 return "pae" in self.flags
47
48 @property
49 def capable_virt(self):
50 return "vmx" in self.flags or "svm" in self.flags
51
52
53class ProfileHypervisor(ProfileDict):
54 def __repr__(self):
55 return "<%s %s-%s>" % (self.__class__.__name__, self.vendor, self.type)
56
57 @property
58 def vendor(self):
59 return self._data.get("vendor")
60
61 @property
62 def model(self):
63 return self._data.get("model")
64
65 @property
66 def type(self):
67 return self._data.get("type")
68
69
70class ProfileDevice(ProfileDict):
71 subsystem2class = {
72 "pci" : hwdata.PCI,
73 "usb" : hwdata.USB,
74 }
75
76 @property
77 def model(self):
78 return self._data.get("model")
79
80 @property
81 def model_string(self):
82 cls = self.subsystem2class[self.subsystem]
83
84 return cls().get_device(self.vendor, self.model)
85
86 @property
87 def subsystem(self):
88 return self._data.get("subsystem")
89
90 @property
91 def vendor(self):
92 return self._data.get("vendor")
93
94 @property
95 def vendor_string(self):
96 cls = self.subsystem2class[self.subsystem]
97
98 return cls().get_vendor(self.vendor)
99
100 @property
101 def driver(self):
102 return self._data.get("driver")
103
104
105class Profile(ProfileDict):
106 def __init__(self, public_id, updated, data):
107 ProfileDict.__init__(self, data)
108
109 self.public_id = public_id
110 self.updated = updated
111
112 def __repr__(self):
113 return "<%s %s>" % (self.__class__.__name__, self.public_id)
114
115 @property
116 def cpu(self):
117 return ProfileCPU(self._data.get("cpu"))
118
119 @property
120 def devices(self):
121 devices = []
122 for d in self._data.get("devices"):
123 d = ProfileDevice(d)
124
125 if d.driver in ("usb", "hub"):
126 continue
127
128 devices.append(d)
129
130 return devices
131
132 @property
133 def hypervisor(self):
134 if self.virtual:
135 return ProfileHypervisor(self._data.get("hypervisor"))
136
137 @property
138 def virtual(self):
139 return self.system.get("virtual")
140
141 @property
142 def system(self):
143 return self._data.get("system")
144
145 @property
146 def release(self):
147 return self.system.get("release")
148
149 @property
150 def kernel(self):
151 return self.system.get("kernel_release")
152
153 @property
154 def memory(self):
155 return self.system.get("memory")
156
157 @property
158 def root_size(self):
159 return self.system.get("root_size")
160
161
162
163class Stasy(object):
164 __metaclass__ = Singleton
165
166 def __init__(self):
167 # Initialize database connection
168 self._conn = pymongo.Connection(DATABASE_HOST)
169 self._db = self._conn[DATABASE_NAME]
170
171 def get_profile_count(self):
172 # XXX need to implement something to get profiles updated since
173 # a given date
174
175 # All distinct profiles (based on public_id)
176 return self._db.profiles.distinct("public_id").count()
177
178 #def _get_profile_cursor(self, public_id):
179 # c = self._db.profiles.find({ "public_id" : public_id })
180 # c.sort("updated", pymongo.ASCENDING)
181 #
182 # return c
183
184 def get_profile(self, public_id):
185 # XXX should only find one object in the end
186 for p in self._db.profiles.find({ "public_id" : public_id }):
187 p = Profile(p.get("public_id"), p.get("updated"), p.get("profile"))
188
189 return p
190
191 def get_profiles(self):
192 # XXX needs nicer database query
193 profiles = []
194 for p in self._db.profiles.find():
195 if not p.get("public_id") in profiles:
196 profiles.append(p.get("public_id"))
197
198 return profiles
199
200 @property
201 def secret_ids(self):
202 return self._db.profiles.distinct("secret_id")
203
204 @property
205 def cpus(self):
206 return self._db.profiles.distinct("profile.cpu")
207
208 @property
209 def cpu_vendors(self):
210 return self._db.profiles.distinct("profile.cpu.vendor")
211
212 @property
213 def cpu_map(self):
214 cpus = {}
215
216 for vendor in self.cpu_vendors:
217 cpus[vendor] = \
218 self._db.profiles.find({
219 "profile.cpu.vendor" : vendor
220 }).count()
221
222 return cpus
223
224 @property
225 def memory_map(self):
226 memory = {}
227
228 for i in range(len(MEMORY_CONSTRAINTS) - 1):
229 min, max = MEMORY_CONSTRAINTS[i:i+2]
230
231 memory[min, max] = \
232 self._db.profiles.find(
233 { "profile.system.memory" : {
234 "$gte" : min * 1024, "$lt" : max * 1024
235 }
236 }).count()
237
238 return memory
239
240 @property
241 def memory_average(self):
242 memory = 0
243
244 all = self._db.profiles.find()
245
246 # XXX ugly. needs to be done by group()
247 for m in all:
248 if not m.has_key("profile"):
249 continue
250 memory += int(m.get("profile").get("system").get("memory"))
251
252 return (memory / all.count()) / 1024
253
254 @property
255 def hypervisor_vendors(self):
256 return self._db.profiles.distinct("profile.hypervisor.vendor")
257
258 @property
259 def hypervisor_map(self):
260 hypervisors = {}
261
262 for hypervisor in self.hypervisor_vendors:
263 hypervisors[hypervisor] = \
264 self._db.profiles.find({
265 "profile.hypervisor.vendor" : hypervisor
266 }).count()
267
268 return hypervisors
269
270 @property
271 def hypervisor_models(self):
272 return self._db.profiles.distinct("profile.hypervisor.model")
273
274 @property
275 def virtual_map(self):
276 virtual = {
277 True: None,
278 False: None,
279 }
280
281 for k in virtual.keys():
282 virtual[k] = \
283 self._db.profiles.find({ "profile.system.virtual": k }).count()
284
285 return virtual
286
287 @property
288 def languages(self):
289 return self._db.profiles.distinct("profile.system.language")
290
291 @property
292 def vendors(self):
293 return self._db.profiles.distinct("profile.system.vendor")
294
295 @property
296 def vendor_map(self):
297 vendors = {}
298
299 for vendor in self.vendors:
300 vendors[vendor] = \
301 self._db.profiles.find({
302 "profile.system.vendor" : vendor
303 }).count()
304
305 return vendors
306
307 @property
308 def models(self):
309 return self._db.profiles.distinct("profile.system.model")
310
311
312
313if __name__ == "__main__":
314 s = Stasy()
315
316 print s.get_profile("0" * 40)
317 print s.cpu_vendors
318 for id in s.secret_ids:
319 print "\t", id
320
321 #for p in s._db.profiles.find():
322 # print p
323
324 print s.cpu_map
325 print s.memory_map
326 print s.memory_average
327 print s.hypervisor_vendors
328 print s.hypervisor_models
329 print s.languages
330 print s.vendors
331 print s.vendor_map
332 print s.models
333 print s.cpus
334
335 p = s.get_profile("0b5f4fe2162fdfbfa29b632610e317078fa70d34")
336 print p
337 print p.hypervisor