]> git.ipfire.org Git - oddments/fireinfo.git/blob - fireinfo/system.py
New class and C functions for hypervisor detection.
[oddments/fireinfo.git] / fireinfo / system.py
1 #!/usr/bin/python
2
3 import hashlib
4 import json
5 import os
6 import string
7
8 import cpu
9 import device
10 import hypervisor
11
12 class System(object):
13
14 def __init__(self):
15 # find all devices
16 self.devices = []
17 self.scan()
18 self.cpu = cpu.CPU()
19 self.hypervisor = hypervisor.Hypervisor()
20
21 def profile(self):
22 p = {
23 "public_id" : self.public_id,
24 "private_id" : self.private_id,
25
26 "arch" : self.arch,
27 "language" : self.language,
28 "release" : self.release,
29 "memory" : self.memory,
30 "kernel" : self.kernel,
31 "root_size" : self.root_size,
32 "devices" : [],
33
34 "virtual" : self.virtual,
35 }
36
37 for device in self.devices:
38 p["devices"].append({
39 "subsystem" : device.subsystem.lower(),
40 "vendor" : device.vendor.lower(),
41 "model" : device.model.lower(),
42 "deviceclass" : device.deviceclass
43 })
44
45 p["cpu"] = {
46 "vendor" : self.cpu.vendor,
47 "model" : self.cpu.model,
48 "stepping" : self.cpu.stepping,
49 "flags" : self.cpu.flags,
50 "bogomips" : self.cpu.bogomips,
51 "speed" : self.cpu.speed,
52 "hypervisor" : self.cpu.hypervisor,
53 "virtype" : self.cpu.virtype,
54 "family" : self.cpu.family,
55 "count" : self.cpu.count
56 }
57
58 # Only append hypervisor information if we are virtualized.
59 if self.virtual:
60 p["hypervisor"] = {
61 "type" : self.hypervisor.type,
62 "vendor" : self.hypervisor.vendor,
63 }
64
65 return json.dumps(p)
66
67
68 @property
69 def arch(self):
70 return os.uname()[4]
71
72 @property
73 def public_id(self):
74 """
75 This returns a globally (hopefully) ID to identify the host
76 later (by request) in the database.
77 """
78 return hashlib.sha1(self._unique_id).hexdigest()
79
80 @property
81 def private_id(self):
82 """
83 The private ID is built out of the _unique_id and used to
84 permit a host to do changes on the database.
85
86 No one could ever guess this without access to the host.
87 """
88 return hashlib.sha1("%s" % reversed(self._unique_id)).hexdigest()
89
90 @property
91 def _unique_id(self):
92 """
93 This is a helper ID which is generated out of some hardware information
94 that is considered to be constant over a PC's lifetime.
95
96 None of the data here is ever sent to the server.
97 """
98 return "123456789" # XXX just a dummy
99
100 @property
101 def language(self):
102 with open("/var/ipfire/main/settings", "r") as f:
103 for line in f.readlines():
104 key, val = line.split("=", 1)
105 if key=="LANGUAGE":
106 return val.strip()
107
108 @property
109 def release(self):
110 with open("/etc/system-release", "r") as f:
111 return f.read().strip()
112
113 @property
114 def memory(self):
115 with open("/proc/meminfo", "r") as f:
116 firstline = f.readline().strip()
117 return firstline.split()[1]
118
119 @property
120 def kernel(self):
121 return os.uname()[2]
122
123 @property
124 def root_disk(self):
125 with open("/etc/mtab", "r") as f:
126 dev, mountpoint, rest = f.readline().split(" ",2)
127 if mountpoint == "/":
128 dev = dev[5:]
129 # cut off all digits at end of string
130 while dev[-1] in string.digits:
131 dev = dev[:-1]
132 return dev
133
134 @property
135 def root_size(self):
136 path="/sys/block/%s/size" %self.root_disk
137 if not os.path.exists(path):
138 return
139 with open(path, "r") as f:
140 return int(f.readline())*512/1024
141
142 def scan(self):
143 toscan = (("/sys/bus/pci/devices", device.PCIDevice),
144 ("/sys/bus/usb/devices", device.USBDevice))
145 for path, cls in toscan:
146 dirlist = os.listdir(path)
147 for dir in dirlist:
148 self.devices.append(cls(os.path.join(path, dir)))
149
150 @property
151 def virtual(self):
152 """
153 Say if the host is running in a virtual environment.
154 """
155 return self.hypervisor.virtual
156
157
158
159 if __name__ == "__main__":
160 s=System()
161 print s.arch
162 print s.language
163 print s.release
164 print s.memory
165 print s.kernel
166 print s.root_disk
167 print s.root_size
168 print "------------\n", s.devices, "\n------------\n"
169 print s.profile()
170
171 import urllib2
172 import urllib
173 r = urllib2.Request("http://192.168.10.101:9001/send/%s" %s.public_id, data = urllib.urlencode({"profile" : s.profile()}))
174 urllib2.urlopen(r)