| 1 | #!/usr/bin/env python |
|---|
| 2 | ############################################################################ |
|---|
| 3 | # |
|---|
| 4 | # DSAGE: Distributed SAGE |
|---|
| 5 | # |
|---|
| 6 | # Copyright (C) 2006, 2007 Yi Qiang <yqiang@gmail.com> |
|---|
| 7 | # |
|---|
| 8 | # Distributed under the terms of the GNU General Public License (GPL) |
|---|
| 9 | # |
|---|
| 10 | # This code is distributed in the hope that it will be useful, |
|---|
| 11 | # but WITHOUT ANY WARRANTY; without even the implied warranty of |
|---|
| 12 | # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU |
|---|
| 13 | # General Public License for more details. |
|---|
| 14 | # |
|---|
| 15 | # The full text of the GPL is available at: |
|---|
| 16 | # |
|---|
| 17 | # http://www.gnu.org/licenses/ |
|---|
| 18 | ############################################################################ |
|---|
| 19 | |
|---|
| 20 | import sys |
|---|
| 21 | import os |
|---|
| 22 | from twisted.spread import pb |
|---|
| 23 | from twisted.internet import reactor, utils, defer |
|---|
| 24 | from twisted.python import log |
|---|
| 25 | |
|---|
| 26 | class HostInfo(pb.Copyable, pb.RemoteCopy): |
|---|
| 27 | """ |
|---|
| 28 | Class to gather computer specifications on the running host. |
|---|
| 29 | |
|---|
| 30 | """ |
|---|
| 31 | |
|---|
| 32 | def __str__(self): |
|---|
| 33 | return str(self.host_info) |
|---|
| 34 | |
|---|
| 35 | def __repr__(self): |
|---|
| 36 | return str(self.host_info) |
|---|
| 37 | |
|---|
| 38 | def _catch_failure(self, failure): |
|---|
| 39 | log.msg("Error: ", failure.getErrorMessage()) |
|---|
| 40 | log.msg("Traceback: ", failure.printTraceback()) |
|---|
| 41 | |
|---|
| 42 | def _gotsysctl(self, output, host_info): |
|---|
| 43 | d = defer.Deferred() |
|---|
| 44 | output = output.split('\n') |
|---|
| 45 | for line in output: |
|---|
| 46 | if line == '': |
|---|
| 47 | continue |
|---|
| 48 | l = line.strip() |
|---|
| 49 | if '=' in l: |
|---|
| 50 | l = l.split('=') |
|---|
| 51 | elif ':' in line: |
|---|
| 52 | l = l.split(':') |
|---|
| 53 | |
|---|
| 54 | l = [li.strip() for li in l] |
|---|
| 55 | if l[0] == 'hw.cpufrequency': |
|---|
| 56 | host_info['cpu Mhz'] = (int(l[1]) / 1000000.0) |
|---|
| 57 | elif l[0] == 'hw.availcpu': |
|---|
| 58 | host_info['cpus'] = int(l[1]) |
|---|
| 59 | elif l[0] == 'hw.physmem': |
|---|
| 60 | host_info['MemTotal'] = int(l[1]) |
|---|
| 61 | elif l[0] == 'hw.usermem': |
|---|
| 62 | host_info['MemFree'] = (host_info['MemTotal'] - |
|---|
| 63 | int(l[1])) / 1024 / 1024 |
|---|
| 64 | elif l[0] == 'machdep.cpu.brand_string': |
|---|
| 65 | host_info['cpu model'] = l[1] |
|---|
| 66 | |
|---|
| 67 | self.canonical_info(host_info) |
|---|
| 68 | d.callback(self.host_info) |
|---|
| 69 | return d |
|---|
| 70 | |
|---|
| 71 | def get_host_info(self): |
|---|
| 72 | platform = sys.platform |
|---|
| 73 | host_info = {} |
|---|
| 74 | if platform == 'linux2' or platform == 'linux': |
|---|
| 75 | d = defer.Deferred() |
|---|
| 76 | host_info['os'] = platform |
|---|
| 77 | cpuinfo = open('/proc/cpuinfo','r').readlines() |
|---|
| 78 | |
|---|
| 79 | cpus = 0 |
|---|
| 80 | for line in cpuinfo: |
|---|
| 81 | line = line.replace('\n','') |
|---|
| 82 | line = line.replace('\t','') |
|---|
| 83 | if line == '': |
|---|
| 84 | continue |
|---|
| 85 | if 'processor' in line: |
|---|
| 86 | cpus += 1 |
|---|
| 87 | s = line.split(':') |
|---|
| 88 | if s != ['\n']: |
|---|
| 89 | host_info[s[0].strip()] = s[1].strip() |
|---|
| 90 | |
|---|
| 91 | host_info['cpus'] = cpus |
|---|
| 92 | |
|---|
| 93 | # uptime |
|---|
| 94 | uptime = open('/proc/uptime', 'r').readline().split(' ') |
|---|
| 95 | host_info['uptime'] = uptime[0] |
|---|
| 96 | |
|---|
| 97 | # memory info |
|---|
| 98 | meminfo = open('/proc/meminfo', 'r').readlines() |
|---|
| 99 | for line in meminfo: |
|---|
| 100 | s = line.split(':') |
|---|
| 101 | if s != ['\n']: |
|---|
| 102 | host_info[s[0].strip()] = s[1].strip() |
|---|
| 103 | |
|---|
| 104 | # hostname |
|---|
| 105 | hostname = os.popen('hostname').readline().strip() |
|---|
| 106 | host_info['hostname'] = hostname |
|---|
| 107 | |
|---|
| 108 | # kernel version |
|---|
| 109 | kernel_version = os.popen('uname -r').readline().strip() |
|---|
| 110 | host_info['kernel_version'] = kernel_version |
|---|
| 111 | |
|---|
| 112 | host_info['os'] = platform |
|---|
| 113 | d.callback(self.canonical_info(host_info)) |
|---|
| 114 | return d |
|---|
| 115 | |
|---|
| 116 | if platform == 'darwin': |
|---|
| 117 | """OS X Worker. """ |
|---|
| 118 | cmd = '/usr/sbin/sysctl' |
|---|
| 119 | args = ('-a', 'hw') |
|---|
| 120 | d = utils.getProcessOutput(cmd, args, errortoo=1) |
|---|
| 121 | d.addCallback(self._gotsysctl, host_info) |
|---|
| 122 | d.addErrback(self._catch_failure) |
|---|
| 123 | return d |
|---|
| 124 | |
|---|
| 125 | def canonical_info(self, platform_host_info): |
|---|
| 126 | """Standarize host info so we can parse it easily""" |
|---|
| 127 | |
|---|
| 128 | unify_info = {'model name': 'cpu_model', |
|---|
| 129 | 'cpu Mhz': 'cpu_speed', |
|---|
| 130 | 'MemTotal': 'mem_total', |
|---|
| 131 | 'MemFree': 'mem_free', |
|---|
| 132 | 'kernel_version': 'os', |
|---|
| 133 | 'cpu family': 'cpu_model', |
|---|
| 134 | 'cpu model': 'cpu_model', |
|---|
| 135 | 'cache size': 'cpu_cache_size', |
|---|
| 136 | 'fpu': 'fpu', |
|---|
| 137 | 'hostname': 'hostname', |
|---|
| 138 | 'cpus': 'cpus', |
|---|
| 139 | 'ip': 'ip', |
|---|
| 140 | 'os': 'os' |
|---|
| 141 | } |
|---|
| 142 | |
|---|
| 143 | canonical_info = {} |
|---|
| 144 | for k,v in platform_host_info.iteritems(): |
|---|
| 145 | try: |
|---|
| 146 | canonical_info[unify_info[k]] = v |
|---|
| 147 | except KeyError: |
|---|
| 148 | pass |
|---|
| 149 | |
|---|
| 150 | try: |
|---|
| 151 | import sage.version |
|---|
| 152 | canonical_info['sage_version'] = sage.version.version |
|---|
| 153 | except ImportError: |
|---|
| 154 | canonical_info['sage_version'] = 'unknown' |
|---|
| 155 | |
|---|
| 156 | self.host_info = canonical_info |
|---|
| 157 | |
|---|
| 158 | return self.host_info |
|---|
| 159 | |
|---|
| 160 | class ClassicHostInfo(object): |
|---|
| 161 | """ |
|---|
| 162 | Class to gather computer specifications on the running host. |
|---|
| 163 | |
|---|
| 164 | """ |
|---|
| 165 | |
|---|
| 166 | def __init__(self): |
|---|
| 167 | self.host_info = self.get_host_info(sys.platform) |
|---|
| 168 | |
|---|
| 169 | def __str__(self): |
|---|
| 170 | return str(self.host_info) |
|---|
| 171 | |
|---|
| 172 | def __repr__(self): |
|---|
| 173 | return str(self.host_info) |
|---|
| 174 | |
|---|
| 175 | def get_host_info(self, platform): |
|---|
| 176 | host_info = {} |
|---|
| 177 | host_info['os'] = platform |
|---|
| 178 | if platform in ('linux', 'linux2', 'cygwin'): |
|---|
| 179 | cpuinfo = open('/proc/cpuinfo','r').readlines() |
|---|
| 180 | cpus = 0 |
|---|
| 181 | for line in cpuinfo: |
|---|
| 182 | if 'processor' in line: |
|---|
| 183 | cpus += 1 |
|---|
| 184 | s = line.split(':') |
|---|
| 185 | if s != ['\n']: |
|---|
| 186 | if s[0].strip() == 'cpu MHz': |
|---|
| 187 | host_info[s[0].strip()] = int(s[1].strip()) |
|---|
| 188 | else: |
|---|
| 189 | host_info[s[0].strip()] = s[1].strip() |
|---|
| 190 | host_info['cpus'] = cpus |
|---|
| 191 | |
|---|
| 192 | uptime = open('/proc/uptime', 'r').readline().split(' ') |
|---|
| 193 | host_info['uptime'] = int(uptime[0]) |
|---|
| 194 | |
|---|
| 195 | meminfo = open('/proc/meminfo', 'r').readlines() |
|---|
| 196 | for line in meminfo: |
|---|
| 197 | s = line.split(':') |
|---|
| 198 | if s != ['\n']: |
|---|
| 199 | if s[0].strip() == 'MemTotal': |
|---|
| 200 | mem_total = int(int(s[1].split()[0].strip()) / 1024) |
|---|
| 201 | host_info[s[0].strip()] = mem_total |
|---|
| 202 | elif s[0].strip() == 'MemFree': |
|---|
| 203 | mem_free = int(int(s[1].split()[0].strip()) / 1024) |
|---|
| 204 | host_info[s[0].strip()] = mem_free |
|---|
| 205 | else: |
|---|
| 206 | host_info[s[0].strip()] = s[1].strip() |
|---|
| 207 | |
|---|
| 208 | hostname = os.popen('hostname').readline().strip() |
|---|
| 209 | host_info['hostname'] = hostname |
|---|
| 210 | |
|---|
| 211 | kernel_version = os.popen('uname -r').readline().strip() |
|---|
| 212 | host_info['kernel_version'] = kernel_version |
|---|
| 213 | |
|---|
| 214 | if not host_info.has_key('model name'): |
|---|
| 215 | model = os.popen('uname -p').readline().strip() |
|---|
| 216 | host_info['model name'] = model |
|---|
| 217 | if platform == 'darwin': |
|---|
| 218 | for line in os.popen('sysctl -a hw machdep').readlines(): |
|---|
| 219 | l = line.strip() |
|---|
| 220 | if '=' in l: |
|---|
| 221 | l = l.split('=') |
|---|
| 222 | if ':' in line: |
|---|
| 223 | l = l.split(':') |
|---|
| 224 | |
|---|
| 225 | l = [li.strip() for li in l] |
|---|
| 226 | if l[0] == 'hw.cpufrequency': |
|---|
| 227 | host_info['cpu MHz'] = str(int(l[1]) / 1000000) |
|---|
| 228 | elif l[0] == 'hw.availcpu': |
|---|
| 229 | host_info['cpus'] = int(l[1]) |
|---|
| 230 | elif l[0] == 'hw.physmem': |
|---|
| 231 | host_info['MemTotal'] = int(int(l[1]) / (1024*1024)) |
|---|
| 232 | elif l[0] == 'hw.usermem': |
|---|
| 233 | mem_total = int(host_info['MemTotal']) |
|---|
| 234 | user_mem = int(l[1]) / (1024*1024) |
|---|
| 235 | mem_free = int(mem_total - user_mem) |
|---|
| 236 | host_info['MemFree'] = mem_free |
|---|
| 237 | elif l[0] == 'machdep.cpu.brand_string': |
|---|
| 238 | host_info['model name'] = l[1] |
|---|
| 239 | elif l[0] == 'hw.model': # OS X PPC |
|---|
| 240 | host_info['model name'] = l[1] |
|---|
| 241 | |
|---|
| 242 | # hostname |
|---|
| 243 | hostname = os.popen('hostname').readline().strip() |
|---|
| 244 | host_info['hostname'] = hostname |
|---|
| 245 | |
|---|
| 246 | # kernel version |
|---|
| 247 | kernel_version = os.popen('uname -r').readline().strip() |
|---|
| 248 | host_info['kernel_version'] = kernel_version |
|---|
| 249 | |
|---|
| 250 | return self.canonical_info(host_info) |
|---|
| 251 | |
|---|
| 252 | def canonical_info(self, platform_host_info): |
|---|
| 253 | """ |
|---|
| 254 | Standarize host info so we can parse it easily. |
|---|
| 255 | |
|---|
| 256 | """ |
|---|
| 257 | |
|---|
| 258 | unify_info = {'model name': 'cpu_model', |
|---|
| 259 | 'cpu MHz': 'cpu_speed', |
|---|
| 260 | 'MemTotal': 'mem_total', |
|---|
| 261 | 'MemFree': 'mem_free', |
|---|
| 262 | 'kernel_version': 'kernel_version', |
|---|
| 263 | 'cache size': 'cpu_cache_size', |
|---|
| 264 | 'fpu': 'fpu', |
|---|
| 265 | 'hostname': 'hostname', |
|---|
| 266 | 'cpus': 'cpus', |
|---|
| 267 | 'ip': 'ip', |
|---|
| 268 | 'os': 'os'} |
|---|
| 269 | canonical_info = {} |
|---|
| 270 | for k,v in platform_host_info.iteritems(): |
|---|
| 271 | try: |
|---|
| 272 | canonical_info[unify_info[k]] = v |
|---|
| 273 | except KeyError: |
|---|
| 274 | pass |
|---|
| 275 | |
|---|
| 276 | try: |
|---|
| 277 | import sage.version |
|---|
| 278 | canonical_info['sage_version'] = sage.version.version |
|---|
| 279 | except ImportError: |
|---|
| 280 | canonical_info['sage_version'] = 'unknown' |
|---|
| 281 | |
|---|
| 282 | return canonical_info |
|---|
| 283 | |
|---|
| 284 | if __name__ == '__main__': |
|---|
| 285 | h = ClassicHostInfo() |
|---|
| 286 | print h |
|---|