00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025
00026
00027
00028
00029
00030
00031
00032
00033
00034 from i18n import _
00035
00036
00037 import platform
00038 import software
00039 import commands
00040 import urlgrabber.grabber
00041 import sys
00042 import os
00043 from urlparse import urljoin
00044 from urlparse import urlparse
00045 from urllib import urlencode
00046 import urllib
00047 import json
00048 from json import JSONEncoder
00049 import datetime
00050 import logging
00051
00052 import config
00053 from smolt_config import get_config_attr
00054 from fs_util import get_fslist
00055 from devicelist import cat
00056
00057 from devicelist import get_device_list
00058 import logging
00059 from logging.handlers import RotatingFileHandler
00060 import codecs
00061 import MultipartPostHandler
00062 import urllib2
00063
00064 try:
00065 import subprocess
00066 except ImportError, e:
00067 pass
00068
00069
00070 WITHHELD_MAGIC_STRING = 'WITHHELD'
00071 SELINUX_ENABLED = 1
00072 SELINUX_DISABLED = 0
00073 SELINUX_WITHHELD = -1
00074
00075
00076 fs_types = get_config_attr("FS_TYPES", ["ext2", "ext3", "xfs", "reiserfs"])
00077 fs_mounts = dict.fromkeys(get_config_attr("FS_MOUNTS", ["/", "/home", "/etc", "/var", "/boot"]), True)
00078 fs_m_filter = get_config_attr("FS_M_FILTER", False)
00079 fs_t_filter = get_config_attr("FS_T_FILTER", False)
00080
00081 smoonURL = get_config_attr("SMOON_URL", "http://smolts.org/")
00082 secure = get_config_attr("SECURE", 0)
00083 hw_uuid_file = get_config_attr("HW_UUID", "/etc/smolt/hw-uuid")
00084 admin_token_file = get_config_attr("ADMIN_TOKEN", '' )
00085
00086 clientVersion = '1.3.2'
00087 smoltProtocol = '0.97'
00088 supported_protocols = ['0.97',]
00089 user_agent = 'smolt/%s' % smoltProtocol
00090 timeout = 120.0
00091 proxies = None
00092 DEBUG = False
00093
00094
00095 PCI_BASE_CLASS_STORAGE = 1
00096 PCI_CLASS_STORAGE_SCSI = 0
00097 PCI_CLASS_STORAGE_IDE = 1
00098 PCI_CLASS_STORAGE_FLOPPY = 2
00099 PCI_CLASS_STORAGE_IPI = 3
00100 PCI_CLASS_STORAGE_RAID = 4
00101 PCI_CLASS_STORAGE_OTHER = 80
00102
00103 PCI_BASE_CLASS_NETWORK = 2
00104 PCI_CLASS_NETWORK_ETHERNET = 0
00105 PCI_CLASS_NETWORK_TOKEN_RING = 1
00106 PCI_CLASS_NETWORK_FDDI = 2
00107 PCI_CLASS_NETWORK_ATM = 3
00108 PCI_CLASS_NETWORK_OTHER = 80
00109 PCI_CLASS_NETWORK_WIRELESS = 128
00110
00111 PCI_BASE_CLASS_DISPLAY = 3
00112 PCI_CLASS_DISPLAY_VGA = 0
00113 PCI_CLASS_DISPLAY_XGA = 1
00114 PCI_CLASS_DISPLAY_3D = 2
00115 PCI_CLASS_DISPLAY_OTHER = 80
00116
00117 PCI_BASE_CLASS_MULTIMEDIA = 4
00118 PCI_CLASS_MULTIMEDIA_VIDEO = 0
00119 PCI_CLASS_MULTIMEDIA_AUDIO = 1
00120 PCI_CLASS_MULTIMEDIA_PHONE = 2
00121 PCI_CLASS_MULTIMEDIA_HD_AUDIO = 3
00122 PCI_CLASS_MULTIMEDIA_OTHER = 80
00123
00124 PCI_BASE_CLASS_BRIDGE = 6
00125 PCI_CLASS_BRIDGE_HOST = 0
00126 PCI_CLASS_BRIDGE_ISA = 1
00127 PCI_CLASS_BRIDGE_EISA = 2
00128 PCI_CLASS_BRIDGE_MC = 3
00129 PCI_CLASS_BRIDGE_PCI = 4
00130 PCI_CLASS_BRIDGE_PCMCIA = 5
00131 PCI_CLASS_BRIDGE_NUBUS = 6
00132 PCI_CLASS_BRIDGE_CARDBUS = 7
00133 PCI_CLASS_BRIDGE_RACEWAY = 8
00134 PCI_CLASS_BRIDGE_OTHER = 80
00135
00136 PCI_BASE_CLASS_COMMUNICATION = 7
00137 PCI_CLASS_COMMUNICATION_SERIAL = 0
00138 PCI_CLASS_COMMUNICATION_PARALLEL = 1
00139 PCI_CLASS_COMMUNICATION_MULTISERIAL = 2
00140 PCI_CLASS_COMMUNICATION_MODEM = 3
00141 PCI_CLASS_COMMUNICATION_OTHER = 80
00142
00143 PCI_BASE_CLASS_INPUT = 9
00144 PCI_CLASS_INPUT_KEYBOARD = 0
00145 PCI_CLASS_INPUT_PEN = 1
00146 PCI_CLASS_INPUT_MOUSE = 2
00147 PCI_CLASS_INPUT_SCANNER = 3
00148 PCI_CLASS_INPUT_GAMEPORT = 4
00149 PCI_CLASS_INPUT_OTHER = 80
00150
00151 PCI_BASE_CLASS_SERIAL = 12
00152 PCI_CLASS_SERIAL_FIREWIRE = 0
00153 PCI_CLASS_SERIAL_ACCESS = 1
00154
00155 PCI_CLASS_SERIAL_SSA = 2
00156 PCI_CLASS_SERIAL_USB = 3
00157 PCI_CLASS_SERIAL_FIBER = 4
00158 PCI_CLASS_SERIAL_SMBUS = 5
00159
00160
00161
00162 FORMFACTOR_LIST = [ "Unknown",
00163 "Other",
00164 "Unknown",
00165 "Desktop",
00166 "Low Profile Desktop",
00167 "Pizza Box",
00168 "Mini Tower",
00169 "Tower",
00170 "Portable",
00171 "Laptop",
00172 "Notebook",
00173 "Hand Held",
00174 "Docking Station",
00175 "All In One",
00176 "Sub Notebook",
00177 "Space-saving",
00178 "Lunch Box",
00179 "Main Server Chassis",
00180 "Expansion Chassis",
00181 "Sub Chassis",
00182 "Bus Expansion Chassis",
00183 "Peripheral Chassis",
00184 "RAID Chassis",
00185 "Rack Mount Chassis",
00186 "Sealed-case PC",
00187 "Multi-system",
00188 "CompactPCI",
00189 "AdvancedTCA"
00190 ]
00191
00192 def to_ascii(o, current_encoding='utf-8'):
00193 if not isinstance(o, basestring):
00194 return o
00195
00196 if isinstance(o, unicode):
00197 s = o
00198 else:
00199 s = unicode(o, current_encoding)
00200 return s
00201
00202
00203 class Host:
00204 def __init__(self, gate, uuid):
00205 cpuInfo = read_cpuinfo()
00206 memory = read_memory()
00207 self.UUID = uuid
00208 self.os = gate.process('distro', software.read_os(), WITHHELD_MAGIC_STRING)
00209 self.defaultRunlevel = gate.process('run_level', software.read_runlevel(), -1)
00210
00211 self.bogomips = gate.process('cpu', cpuInfo.get('bogomips', 0), 0)
00212 self.cpuVendor = gate.process('cpu', cpuInfo.get('type', ''), WITHHELD_MAGIC_STRING)
00213 self.cpuModel = gate.process('cpu', cpuInfo.get('model', ''), WITHHELD_MAGIC_STRING)
00214 self.cpu_stepping = gate.process('cpu', cpuInfo.get('cpu_stepping', 0), 0)
00215 self.cpu_family = gate.process('cpu', cpuInfo.get('cpu_family', ''), '')
00216 self.cpu_model_num = gate.process('cpu', cpuInfo.get('cpu_model_num', 0), 0)
00217 self.numCpus = gate.process('cpu', cpuInfo.get('count', 0), 0)
00218 self.cpuSpeed = gate.process('cpu', cpuInfo.get('speed', 0), 0)
00219
00220 self.systemMemory = gate.process('ram_size', memory['ram'], 0)
00221 self.systemSwap = gate.process('swap_size', memory['swap'], 0)
00222 self.kernelVersion = gate.process('kernel', os.uname()[2], WITHHELD_MAGIC_STRING)
00223 if gate.grants('language'):
00224 try:
00225 self.language = os.environ['LANG']
00226 except KeyError:
00227 try:
00228 status, lang = commands.getstatusoutput("grep LANG /etc/sysconfig/i18n")
00229 if status == 0:
00230 self.language = lang.split('"')[1]
00231 else:
00232 self.language = 'Unknown'
00233 except:
00234 self.language = 'Unknown'
00235 else:
00236 self.language = WITHHELD_MAGIC_STRING
00237
00238 tempform = platform.machine()
00239 self.platform = gate.process('arch', tempform, WITHHELD_MAGIC_STRING)
00240
00241 if gate.grants('vendor'):
00242
00243 try:
00244 self.systemVendor = cat('/sys/devices/virtual/dmi/id/sys_vendor')[0].strip()
00245 except:
00246 self.systemVendor = 'Unknown'
00247 else:
00248 self.systemVendor = WITHHELD_MAGIC_STRING
00249
00250 if gate.grants('model'):
00251 try:
00252 self.systemModel = cat('/sys/devices/virtual/dmi/id/product_name')[0].strip() + ' ' + cat('/sys/devices/virtual/dmi/id/product_version')[0].strip()
00253 except:
00254 self.systemModel = 'Unknown'
00255
00256
00257
00258
00259
00260
00261
00262 else:
00263 self.systemModel = WITHHELD_MAGIC_STRING
00264
00265 if gate.grants('form_factor'):
00266 try:
00267 formfactor_id = int(cat('/sys/devices/virtual/dmi/id/chassis_type')[0].strip())
00268 self.formfactor = FORMFACTOR_LIST[formfactor_id]
00269 except:
00270 self.formfactor = 'Unknown'
00271 else:
00272 self.formfactor = WITHHELD_MAGIC_STRING
00273
00274 if tempform == 'ppc64':
00275 if hostInfo.get('openfirmware.model'):
00276 if hostInfo['openfirmware.model'][:3] == 'IBM':
00277 self.systemVendor = 'IBM'
00278 model = hostInfo['openfirmware.model'][4:8]
00279
00280 model_map = {
00281 '8842':'JS20',
00282 '6779':'JS21',
00283 '6778':'JS21',
00284 '7988':'JS21',
00285 '8844':'JS21',
00286 '0200':'QS20',
00287 '0792':'QS21',
00288 }
00289 try:
00290 model_name = model_map[model]
00291 self.systemModel = gate.process('model', model_name)
00292 self.formfactor = gate.process('form_factor', 'Blade')
00293 except KeyError:
00294 pass
00295
00296 if gate.grants('selinux'):
00297 try:
00298 import selinux
00299 try:
00300 if selinux.is_selinux_enabled() == 1:
00301 self.selinux_enabled = SELINUX_ENABLED
00302 else:
00303 self.selinux_enabled = SELINUX_DISABLED
00304 except:
00305 self.selinux_enabled = SELINUX_DISABLED
00306 try:
00307 self.selinux_policy = selinux.selinux_getpolicytype()[1]
00308 except:
00309 self.selinux_policy = "Unknown"
00310 try:
00311 enforce = selinux.security_getenforce()
00312 if enforce == 0:
00313 self.selinux_enforce = "Permissive"
00314 elif enforce == 1:
00315 self.selinux_enforce = "Enforcing"
00316 elif enforce == -1:
00317 self.selinux_enforce = "Disabled"
00318 else:
00319 self.selinux_enforce = "FUBARD"
00320 except:
00321 self.selinux_enforce = "Unknown"
00322 except ImportError:
00323 self.selinux_enabled = SELINUX_DISABLED
00324 self.selinux_policy = "Not Installed"
00325 self.selinux_enforce = "Not Installed"
00326 else:
00327 self.selinux_enabled = SELINUX_WITHHELD
00328 self.selinux_policy = WITHHELD_MAGIC_STRING
00329 self.selinux_enforce = WITHHELD_MAGIC_STRING
00330
00331
00332 def get_file_systems(gate):
00333 if not gate.grants('file_systems'):
00334 return []
00335
00336 if fs_t_filter:
00337 file_systems = [fs for fs in get_fslist() if fs.fs_type in fs_types]
00338 else:
00339 file_systems = get_fslist()
00340
00341 file_systems = [fs for fs in file_systems if fs.mnt_dev.startswith('/dev/')]
00342
00343 if fs_m_filter:
00344 for fs in file_systems:
00345 if not fs.mnt_pnt in fs_mounts:
00346 fs.mnt_pnt = WITHHELD_MAGIC_STRING
00347 else:
00348 for fs in file_systems:
00349 fs.mnt_pnt = WITHHELD_MAGIC_STRING
00350
00351 return file_systems
00352
00353 def ignoreDevice(device):
00354 ignore = 1
00355 if device.bus == 'Unknown' or device.bus == 'unknown':
00356 return 1
00357 if device.vendorid in (0, None) and device.type == None:
00358 return 1
00359 if device.bus == 'usb' and device.driver == 'hub':
00360 return 1
00361 if device.bus == 'usb' and 'Hub' in device.description:
00362 return 1
00363 if device.bus == 'sound' and device.driver == 'Unknown':
00364 return 1
00365 if device.bus == 'pnp' and device.driver in ('Unknown', 'system'):
00366 return 1
00367 if device.bus == 'block' and device.type == 'DISK':
00368 return 1
00369 if device.bus == 'usb_device' and device.type == None:
00370 return 1
00371 return 0
00372
00373 class ServerError(Exception):
00374 def __init__(self, value):
00375 self.value = value
00376 def __str__(self):
00377 return repr(self.value)
00378
00379 def serverMessage(page):
00380 for line in page.split("\n"):
00381 if 'UUID:' in line:
00382 return line.strip()[6:]
00383 if 'ServerMessage:' in line:
00384 if 'Critical' in line:
00385 raise ServerError, line.split('ServerMessage: ')[1]
00386 else:
00387 print _('Server Message: "%s"') % line.split('ServerMessage: ')[1]
00388
00389 def error(message):
00390 print >> sys.stderr, message
00391
00392 def debug(message):
00393 if DEBUG:
00394 print message
00395
00396 def reset_resolver():
00397 '''Attempt to reset the system hostname resolver.
00398 returns 0 on success, or -1 if an error occurs.'''
00399 try:
00400 import ctypes
00401 try:
00402 resolv = ctypes.CDLL("libresolv.so.2")
00403 r = resolv.__res_init()
00404 except (OSError, AttributeError):
00405 print "Warning: could not find __res_init in libresolv.so.2"
00406 r = -1
00407 return r
00408 except ImportError:
00409
00410
00411 pass
00412
00413 class SystemBusError(Exception):
00414 def __init__(self, message, hint = None):
00415 self.msg = message
00416 self.hint = hint
00417
00418 def __str__(self):
00419 return str(self.msg)
00420
00421 class UUIDError(Exception):
00422 def __init__(self, message):
00423 self.msg = message
00424
00425 def __str__(self):
00426 return str(self.msg)
00427
00428 class PubUUIDError(Exception):
00429 def __init__(self, message):
00430 self.msg = message
00431
00432 def __str__(self):
00433 return str(self.msg)
00434
00435 class _HardwareProfile:
00436 devices = {}
00437 def __init__(self, gate, uuid):
00438
00439
00440
00441
00442
00443
00444
00445
00446
00447
00448
00449
00450
00451 if gate.grants('devices'):
00452 self.devices = get_device_list()
00453
00454
00455
00456
00457
00458
00459
00460
00461
00462
00463
00464
00465
00466
00467
00468
00469
00470
00471
00472
00473
00474
00475
00476
00477
00478
00479
00480
00481
00482
00483
00484
00485
00486
00487
00488
00489
00490
00491
00492
00493
00494
00495
00496
00497
00498
00499
00500
00501
00502
00503
00504
00505
00506
00507
00508
00509
00510
00511
00512
00513 self.host = Host(gate, uuid)
00514
00515 self.fss = get_file_systems(gate)
00516
00517 self.distro_specific = self.get_distro_specific_data(gate)
00518
00519 def get_distro_specific_data(self, gate):
00520 dist_dict = {}
00521 try:
00522 import distros.all
00523 except:
00524 return dist_dict
00525
00526 for d in distros.all.get():
00527 key = d.key()
00528 if d.detected():
00529 logging.info('Distro "%s" detected' % (key))
00530 d.gather(gate, debug=True)
00531 dist_dict[key] = {
00532 'data':d.data(),
00533 'html':d.html(),
00534 'rst':d.rst(),
00535 'rst_excerpt':d.rst_excerpt(),
00536 }
00537 return dist_dict
00538
00539
00540
00541
00542
00543
00544
00545
00546
00547
00548
00549
00550
00551
00552
00553
00554
00555
00556
00557 def get_sendable_devices(self, protocol_version=smoltProtocol):
00558 my_devices = []
00559 for device in self.devices:
00560 try:
00561 Bus = self.devices[device].bus
00562 VendorID = self.devices[device].vendorid
00563 DeviceID = self.devices[device].deviceid
00564 SubsysVendorID = self.devices[device].subsysvendorid
00565 SubsysDeviceID = self.devices[device].subsysdeviceid
00566 Driver = self.devices[device].driver
00567 Type = self.devices[device].type
00568 Description = self.devices[device].description
00569 except:
00570 continue
00571 else:
00572 if not ignoreDevice(self.devices[device]):
00573 my_devices.append({"vendor_id": VendorID,
00574 "device_id": DeviceID,
00575 "subsys_vendor_id": SubsysVendorID,
00576 "subsys_device_id": SubsysDeviceID,
00577 "bus": Bus,
00578 "driver": Driver,
00579 "type": Type,
00580 "description": Description})
00581
00582 return my_devices
00583
00584 def get_sendable_host(self, protocol_version=smoltProtocol):
00585 return {'uuid' : self.host.UUID,
00586 'os' : self.host.os,
00587 'default_runlevel': self.host.defaultRunlevel,
00588 'language' : self.host.language,
00589 'platform' : self.host.platform,
00590 'bogomips' : self.host.bogomips,
00591 'cpu_vendor' : self.host.cpuVendor,
00592 'cpu_model' : self.host.cpuModel,
00593 'cpu_stepping' : self.host.cpu_stepping,
00594 'cpu_family' : self.host.cpu_family,
00595 'cpu_model_num' : self.host.cpu_model_num,
00596 'num_cpus': self.host.numCpus,
00597 'cpu_speed' : self.host.cpuSpeed,
00598 'system_memory' : self.host.systemMemory,
00599 'system_swap' : self.host.systemSwap,
00600 'vendor' : self.host.systemVendor,
00601 'system' : self.host.systemModel,
00602 'kernel_version' : self.host.kernelVersion,
00603 'formfactor' : self.host.formfactor,
00604 'selinux_enabled': self.host.selinux_enabled,
00605 'selinux_policy': self.host.selinux_policy,
00606 'selinux_enforce': self.host.selinux_enforce
00607 }
00608
00609 def get_sendable_fss(self, protocol_version=smoltProtocol):
00610 return [fs.to_dict() for fs in self.fss]
00611
00612 def write_pub_uuid(self, uuiddb, smoonURL, pub_uuid, uuid):
00613 smoonURLparsed=urlparse(smoonURL)
00614 if pub_uuid is None:
00615 return
00616
00617 try:
00618 uuiddb.set_pub_uuid(uuid, smoonURLparsed[1], pub_uuid)
00619 except Exception, e:
00620 sys.stderr.write(_('\tYour pub_uuid could not be written.\n\n'))
00621 return
00622
00623 def write_admin_token(self,smoonURL,admin,admin_token_file):
00624 smoonURLparsed=urlparse(smoonURL)
00625 admin_token_file += ("-"+smoonURLparsed[1])
00626 try:
00627 file(admin_token_file, 'w').write(admin)
00628 except Exception, e:
00629 sys.stderr.write(_('\tYour admin token could not be cached: %s\n' % e))
00630 return
00631
00632 def get_submission_data(self, prefered_protocol=None):
00633 send_host_obj = self.get_sendable_host(prefered_protocol)
00634 send_host_obj['devices'] = self.get_sendable_devices(prefered_protocol)
00635 send_host_obj['fss'] = self.get_sendable_fss(prefered_protocol)
00636 send_host_obj['smolt_protocol'] = prefered_protocol
00637
00638 dist_data_dict = {}
00639 for k, v in self.distro_specific.items():
00640 dist_data_dict[k] = v['data']
00641 send_host_obj['distro_specific'] = dist_data_dict
00642
00643 return send_host_obj
00644
00645 def get_distro_specific_html(self):
00646 lines = []
00647 if not self.distro_specific:
00648 lines.append(_('No distribution-specific data yet'))
00649 else:
00650 for k, v in self.distro_specific.items():
00651 lines.append(v['html'])
00652 return '\n'.join(lines)
00653
00654 def send(self, uuiddb, uuid, user_agent=user_agent, smoonURL=smoonURL, timeout=timeout, proxies=proxies, batch=False):
00655 def serialize(object, human=False):
00656 if human:
00657 indent = 2
00658 sort_keys = True
00659 else:
00660 indent = None
00661 sort_keys = False
00662 return JSONEncoder(indent=indent, sort_keys=sort_keys).encode(object)
00663
00664 reset_resolver()
00665 grabber = urlgrabber.grabber.URLGrabber(user_agent=user_agent, timeout=timeout, proxies=proxies)
00666
00667 try:
00668 token = grabber.urlopen(urljoin(smoonURL + "/", '/tokens/token_json?uuid=%s' % self.host.UUID, False))
00669 except urlgrabber.grabber.URLGrabError, e:
00670 error(_('Error contacting Server: %s') % e)
00671 return (1, None, None)
00672 tok_str = token.read()
00673 try:
00674 try:
00675 tok_obj = json.loads(tok_str)
00676 if tok_obj['prefered_protocol'] in supported_protocols:
00677 prefered_protocol = tok_obj['prefered_protocol']
00678 else:
00679 error(_('Wrong version, server incapable of handling your client'))
00680 return (1, None, None)
00681 tok = tok_obj['token']
00682
00683 except ValueError, e:
00684 error(_('Something went wrong fetching a token'))
00685 finally:
00686 token.close()
00687
00688 send_host_obj = self.get_submission_data(prefered_protocol)
00689
00690
00691 debug('smoon server URL: %s' % smoonURL)
00692
00693 serialized_host_obj_machine = serialize(send_host_obj, human=False)
00694
00695
00696 log_matrix = {
00697 '.json':serialize(send_host_obj, human=True),
00698 '-distro.html':self.get_distro_specific_html(),
00699 '.rst':'\n'.join(map(to_ascii, self.getProfile())),
00700 }
00701 logdir = os.path.expanduser('~/.smolt/')
00702 try:
00703 if not os.path.exists(logdir):
00704 os.mkdir(logdir, 0700)
00705
00706 for k, v in log_matrix.items():
00707 filename = os.path.expanduser(os.path.join(
00708 logdir, 'submission%s' % k))
00709 r = RotatingFileHandler(filename, \
00710 maxBytes=1000000, backupCount=9)
00711 r.stream.write(v)
00712 r.doRollover()
00713 r.close()
00714 os.remove(filename)
00715 except:
00716 pass
00717 del logdir
00718 del log_matrix
00719
00720
00721 debug('sendHostStr: %s' % serialized_host_obj_machine)
00722 debug('Sending Host')
00723
00724 if batch:
00725 entry_point = "/client/batch_add_json"
00726 logging.debug('Submitting in asynchronous mode')
00727 else:
00728 entry_point = "/client/add_json"
00729 logging.debug('Submitting in synchronous mode')
00730 request_url = urljoin(smoonURL + "/", entry_point, False)
00731 logging.debug('Sending request to %s' % request_url)
00732 try:
00733 opener = urllib2.build_opener(MultipartPostHandler.MultipartPostHandler)
00734 params = { 'uuid':self.host.UUID,
00735 'host':serialized_host_obj_machine,
00736 'token':tok,
00737 'smolt_protocol':smoltProtocol}
00738 o = opener.open(request_url, params)
00739
00740 except Exception, e:
00741 error(_('Error contacting Server: %s') % e)
00742 return (1, None, None)
00743 else:
00744 try:
00745 server_response = serverMessage(o.read())
00746 except ServerError, e:
00747 error(_('Error contacting server: %s') % e)
00748 return (1, None, None)
00749
00750 o.close()
00751 if batch:
00752 pub_uuid = None
00753 else:
00754 pub_uuid = server_response
00755 self.write_pub_uuid(uuiddb, smoonURL, pub_uuid, uuid)
00756
00757 try:
00758 admin_token = grabber.urlopen(urljoin(smoonURL + "/", '/tokens/admin_token_json?uuid=%s' % self.host.UUID, False))
00759 except urlgrabber.grabber.URLGrabError, e:
00760 error(_('An error has occured while contacting the server: %s' % e))
00761 sys.exit(1)
00762 admin_str = admin_token.read()
00763 admin_obj = json.loads(admin_str)
00764 if admin_obj['prefered_protocol'] in supported_protocols:
00765 prefered_protocol = admin_obj['prefered_protocol']
00766 else:
00767 error(_('Wrong version, server incapable of handling your client'))
00768 return (1, None, None)
00769 admin = admin_obj['token']
00770
00771 if not admin_token_file == '' :
00772 self.write_admin_token(smoonURL,admin,admin_token_file)
00773 return (0, pub_uuid, admin)
00774
00775 def regenerate_pub_uuid(self, uuiddb, uuid, user_agent=user_agent, smoonURL=smoonURL, timeout=timeout):
00776 grabber = urlgrabber.grabber.URLGrabber(user_agent=user_agent, timeout=timeout)
00777 try:
00778 new_uuid = grabber.urlopen(urljoin(smoonURL + "/", '/client/regenerate_pub_uuid?uuid=%s' % self.host.UUID))
00779 except urlgrabber.grabber.URLGrabError, e:
00780 raise ServerError, str(e)
00781
00782 response = new_uuid.read()
00783 try:
00784 response_dict = json.loads(response)
00785 except Exception, e:
00786 serverMessage(response)
00787 raise ServerError, _('Reply from server could not be interpreted')
00788 else:
00789 try:
00790 pub_uuid = response_dict['pub_uuid']
00791 except KeyError:
00792 raise ServerError, _('Reply from server could not be interpreted')
00793 self.write_pub_uuid(uuiddb, smoonURL, pub_uuid, uuid)
00794 return pub_uuid
00795
00796
00797 def get_general_info_excerpt(self):
00798 d = {
00799 _('OS'):self.host.os,
00800 _('Default run level'):self.host.defaultRunlevel,
00801 _('Language'):self.host.language,
00802 }
00803 lines = []
00804 for k, v in d.items():
00805 lines.append('%s: %s' % (k, v))
00806 lines.append('...')
00807 return '\n'.join(lines)
00808
00809 def get_devices_info_excerpt(self):
00810 lines = []
00811 for i, (VendorID, DeviceID, SubsysVendorID, SubsysDeviceID, Bus, Driver, Type, Description) \
00812 in enumerate(self.deviceIter()):
00813 if i == 3:
00814 break
00815 lines.append('(%s:%s:%s:%s) %s, %s, %s, %s' % (VendorID, DeviceID, SubsysVendorID, \
00816 SubsysDeviceID, Bus, Driver, Type, Description))
00817 lines.append('...')
00818 return '\n'.join(lines)
00819
00820 def get_file_system_info_excerpt(self):
00821 lines = []
00822 lines.append('device mtpt type bsize frsize blocks bfree bavail file ffree favail')
00823 for i, v in enumerate(self.fss):
00824 if i == 2:
00825 break
00826 lines.append(str(v))
00827 lines.append('...')
00828 return '\n'.join(lines)
00829
00830 def get_distro_info_excerpt(self):
00831 for k, v in self.distro_specific.items():
00832 return v['rst_excerpt']
00833 return "No data, yet"
00834
00835 def getProfile(self):
00836 printBuffer = []
00837
00838 printBuffer.append('# ' + _('This is a Smolt report shown within your default pager.'))
00839 printBuffer.append('# ' + _('Below you can see what data you will submit to the server.'))
00840 printBuffer.append('# ' + _('To get back to Smolt exit the pager (try hitting "q").'))
00841 printBuffer.append('#')
00842 printBuffer.append('# ' + _('NOTE: Editing this file does not change the data submitted.'))
00843 printBuffer.append('')
00844 printBuffer.append('')
00845
00846 printBuffer.append(_('General'))
00847 printBuffer.append('=================================')
00848 for label, data in self.hostIter():
00849 try:
00850 printBuffer.append('%s: %s' % (label, data))
00851 except UnicodeDecodeError:
00852 try:
00853 printBuffer.append('%s: %s' % (unicode(label, 'utf-8'), data))
00854 except UnicodeDecodeError:
00855 printBuffer.append('%r: %r' % (label, data))
00856
00857 if self.devices:
00858 printBuffer.append('')
00859 printBuffer.append('')
00860 printBuffer.append(_('Devices'))
00861 printBuffer.append('=================================')
00862
00863 for VendorID, DeviceID, SubsysVendorID, SubsysDeviceID, Bus, Driver, Type, Description in self.deviceIter():
00864 printBuffer.append('(%s:%s:%s:%s) %s, %s, %s, %s' % (VendorID, DeviceID, SubsysVendorID, SubsysDeviceID, Bus, Driver, Type, Description))
00865
00866 printBuffer.append('')
00867 printBuffer.append('')
00868 printBuffer.append(_('Filesystem Information'))
00869 printBuffer.append('=================================')
00870 printBuffer.append('device mtpt type bsize frsize blocks bfree bavail file ffree favail')
00871 printBuffer.append('-------------------------------------------------------------------')
00872 for fs in self.fss:
00873 printBuffer.append(str(fs))
00874
00875 for k, v in self.distro_specific.items():
00876 printBuffer.append('')
00877 printBuffer.append('')
00878 printBuffer.append(v['rst'])
00879
00880 printBuffer.append('')
00881 return printBuffer
00882
00883
00884 def hostIter(self):
00885 '''Iterate over host information.'''
00886 yield _('UUID'), self.host.UUID
00887 yield _('OS'), self.host.os
00888 yield _('Default run level'), self.host.defaultRunlevel
00889 yield _('Language'), self.host.language
00890 yield _('Platform'), self.host.platform
00891 yield _('BogoMIPS'), self.host.bogomips
00892 yield _('CPU Vendor'), self.host.cpuVendor
00893 yield _('CPU Model'), self.host.cpuModel
00894 yield _('CPU Stepping'), self.host.cpu_stepping
00895 yield _('CPU Family'), self.host.cpu_family
00896 yield _('CPU Model Num'), self.host.cpu_model_num
00897 yield _('Number of CPUs'), self.host.numCpus
00898 yield _('CPU Speed'), self.host.cpuSpeed
00899 yield _('System Memory'), self.host.systemMemory
00900 yield _('System Swap'), self.host.systemSwap
00901 yield _('Vendor'), self.host.systemVendor
00902 yield _('System'), self.host.systemModel
00903 yield _('Form factor'), self.host.formfactor
00904 yield _('Kernel'), self.host.kernelVersion
00905 yield _('SELinux Enabled'), self.host.selinux_enabled
00906 yield _('SELinux Policy'), self.host.selinux_policy
00907 yield _('SELinux Enforce'), self.host.selinux_enforce
00908
00909 def deviceIter(self):
00910 '''Iterate over our devices.'''
00911 for device in self.devices:
00912 Bus = self.devices[device].bus
00913 VendorID = self.devices[device].vendorid
00914 DeviceID = self.devices[device].deviceid
00915 SubsysVendorID = self.devices[device].subsysvendorid
00916 SubsysDeviceID = self.devices[device].subsysdeviceid
00917 Driver = self.devices[device].driver
00918 Type = self.devices[device].type
00919 Description = self.devices[device].description
00920
00921 if not ignoreDevice(self.devices[device]):
00922 yield VendorID, DeviceID, SubsysVendorID, SubsysDeviceID, Bus, Driver, Type, Description
00923
00924
00925
00926 def read_cpuinfo():
00927 def get_entry(a, entry):
00928 e = entry.lower()
00929 if not a.has_key(e):
00930 return ""
00931 return a[e]
00932
00933 if not os.access("/proc/cpuinfo", os.R_OK):
00934 return {}
00935
00936 cpulist = open("/proc/cpuinfo", "r").read()
00937 uname = os.uname()[4].lower()
00938
00939
00940
00941
00942
00943
00944
00945 hwdict = { 'class': "CPU",
00946 'desc' : "Processor",
00947 }
00948 if uname[0] == "i" and uname[-2:] == "86" or (uname == "x86_64"):
00949
00950 count = 0
00951 tmpdict = {}
00952 for cpu in cpulist.split("\n\n"):
00953 if not len(cpu):
00954 continue
00955 count = count + 1
00956 if count > 1:
00957 continue
00958 for cpu_attr in cpu.split("\n"):
00959 if not len(cpu_attr):
00960 continue
00961 vals = cpu_attr.split(':')
00962 if len(vals) != 2:
00963
00964 continue
00965 name, value = vals[0].strip(), vals[1].strip()
00966 tmpdict[name.lower()] = value
00967
00968 if uname == "x86_64":
00969 hwdict['platform'] = 'x86_64'
00970 else:
00971 hwdict['platform'] = "i386"
00972
00973 hwdict['count'] = count
00974 hwdict['type'] = get_entry(tmpdict, 'vendor_id')
00975 hwdict['model'] = get_entry(tmpdict, 'model name')
00976 hwdict['model_number'] = get_entry(tmpdict, 'cpu family')
00977 hwdict['model_ver'] = get_entry(tmpdict, 'model')
00978 hwdict['cpu_stepping'] = get_entry(tmpdict, 'stepping')
00979 hwdict['cpu_family'] = get_entry(tmpdict, 'cpu family')
00980 hwdict['cpu_model_num'] = get_entry(tmpdict, 'model')
00981 hwdict['cache'] = get_entry(tmpdict, 'cache size')
00982 hwdict['bogomips'] = get_entry(tmpdict, 'bogomips')
00983 hwdict['other'] = get_entry(tmpdict, 'flags')
00984 mhz_speed = get_entry(tmpdict, 'cpu mhz')
00985 if mhz_speed == "":
00986
00987 mhz_speed = "-1"
00988 try:
00989 hwdict['speed'] = int(round(float(mhz_speed)) - 1)
00990 except ValueError:
00991 hwdict['speed'] = -1
00992
00993
00994 elif uname in["alpha", "alphaev6"]:
00995
00996 tmpdict = {}
00997 for cpu_attr in cpulist.split("\n"):
00998 if not len(cpu_attr):
00999 continue
01000 vals = cpu_attr.split(':')
01001 if len(vals) != 2:
01002
01003 continue
01004 name, value = vals[0].strip(), vals[1].strip()
01005 tmpdict[name.lower()] = value.lower()
01006
01007 hwdict['platform'] = "alpha"
01008 hwdict['count'] = get_entry(tmpdict, 'cpus detected')
01009 hwdict['type'] = get_entry(tmpdict, 'cpu')
01010 hwdict['model'] = get_entry(tmpdict, 'cpu model')
01011 hwdict['model_number'] = get_entry(tmpdict, 'cpu variation')
01012 hwdict['model_version'] = "%s/%s" % (get_entry(tmpdict, 'system type'),
01013 get_entry(tmpdict,'system variation'))
01014 hwdict['model_rev'] = get_entry(tmpdict, 'cpu revision')
01015 hwdict['cache'] = ""
01016 hwdict['bogomips'] = get_entry(tmpdict, 'bogomips')
01017 hwdict['other'] = get_entry(tmpdict, 'platform string')
01018 hz_speed = get_entry(tmpdict, 'cycle frequency [Hz]')
01019
01020 hz_speed = hz_speed.split()
01021 try:
01022 hwdict['speed'] = int(round(float(hz_speed[0]))) / 1000000
01023 except ValueError:
01024 hwdict['speed'] = -1
01025
01026 elif uname in ["ia64"]:
01027 tmpdict = {}
01028 count = 0
01029 for cpu in cpulist.split("\n\n"):
01030 if not len(cpu):
01031 continue
01032 count = count + 1
01033
01034 if count > 1:
01035 continue
01036 for cpu_attr in cpu.split("\n"):
01037 if not len(cpu_attr):
01038 continue
01039 vals = cpu_attr.split(":")
01040 if len(vals) != 2:
01041
01042 continue
01043 name, value = vals[0].strip(), vals[1].strip()
01044 tmpdict[name.lower()] = value.lower()
01045
01046 hwdict['platform'] = uname
01047 hwdict['count'] = count
01048 hwdict['type'] = get_entry(tmpdict, 'vendor')
01049 hwdict['model'] = get_entry(tmpdict, 'family')
01050 hwdict['model_ver'] = get_entry(tmpdict, 'archrev')
01051 hwdict['model_rev'] = get_entry(tmpdict, 'revision')
01052 hwdict['bogomips'] = get_entry(tmpdict, 'bogomips')
01053 mhz_speed = tmpdict['cpu mhz']
01054 try:
01055 hwdict['speed'] = int(round(float(mhz_speed)) - 1)
01056 except ValueError:
01057 hwdict['speed'] = -1
01058 hwdict['other'] = get_entry(tmpdict, 'features')
01059
01060 elif uname in ['ppc64','ppc']:
01061 tmpdict = {}
01062 count = 0
01063 for cpu in cpulist.split("processor"):
01064 if not len(cpu):
01065 continue
01066 count = count + 1
01067
01068 if count > 1:
01069 continue
01070 for cpu_attr in cpu.split("\n"):
01071 if not len(cpu_attr):
01072 continue
01073 vals = cpu_attr.split(":")
01074 if len(vals) != 2:
01075
01076 continue
01077 name, value = vals[0].strip(), vals[1].strip()
01078 tmpdict[name.lower()] = value.lower()
01079
01080 hwdict['platform'] = uname
01081 hwdict['count'] = count
01082 hwdict['model'] = get_entry(tmpdict, "cpu")
01083 hwdict['model_ver'] = get_entry(tmpdict, 'revision')
01084 hwdict['bogomips'] = get_entry(tmpdict, 'bogomips')
01085 hwdict['vendor'] = get_entry(tmpdict, 'machine')
01086 if get_entry(tmpdict, 'cpu').startswith('ppc970'):
01087 hwdict['type'] = 'IBM'
01088 else:
01089 hwdict['type'] = get_entry(tmpdict, 'platform')
01090 hwdict['system'] = get_entry(tmpdict, 'detected as')
01091
01092 mhz_speed = get_entry(tmpdict, 'clock')[:-3]
01093 try:
01094 hwdict['speed'] = int(round(float(mhz_speed)) - 1)
01095 except ValueError:
01096 hwdict['speed'] = -1
01097
01098 elif uname in ["sparc64","sparc"]:
01099 tmpdict = {}
01100 bogomips = 0
01101 for cpu in cpulist.split("\n\n"):
01102 if not len(cpu):
01103 continue
01104
01105 for cpu_attr in cpu.split("\n"):
01106 if not len(cpu_attr):
01107 continue
01108 vals = cpu_attr.split(":")
01109 if len(vals) != 2:
01110
01111 continue
01112 name, value = vals[0].strip(), vals[1].strip()
01113 if name.endswith('Bogo'):
01114 if bogomips == 0:
01115 bogomips = int(round(float(value)) )
01116 continue
01117 continue
01118 tmpdict[name.lower()] = value.lower()
01119 system = ''
01120 if not os.access("/proc/openprom/banner-name", os.R_OK):
01121 system = 'Unknown'
01122 if os.access("/proc/openprom/banner-name", os.R_OK):
01123 system = open("/proc/openprom/banner-name", "r").read()
01124 hwdict['platform'] = uname
01125 hwdict['count'] = get_entry(tmpdict, 'ncpus probed')
01126 hwdict['model'] = get_entry(tmpdict, 'cpu')
01127 hwdict['type'] = get_entry(tmpdict, 'type')
01128 hwdict['model_ver'] = get_entry(tmpdict, 'type')
01129 hwdict['bogomips'] = bogomips
01130 hwdict['vendor'] = 'sun'
01131 hwdict['cache'] = ""
01132 speed = int(round(float(bogomips))) / 2
01133 hwdict['speed'] = speed
01134 hwdict['system'] = system
01135
01136 else:
01137
01138 hwdict['platform'] = uname
01139 hwdict['count'] = 1
01140 hwdict['type'] = uname
01141 hwdict['model'] = uname
01142 hwdict['model_number'] = ""
01143 hwdict['model_ver'] = ""
01144 hwdict['model_rev'] = ""
01145 hwdict['cache'] = ""
01146 hwdict['bogomips'] = ""
01147 hwdict['other'] = ""
01148 hwdict['speed'] = 0
01149
01150
01151 if not hwdict["count"]:
01152 hwdict["count"] = 1
01153 else:
01154 try:
01155 hwdict["count"] = int(hwdict["count"])
01156 except:
01157 hwdict["count"] = 1
01158 else:
01159 if hwdict["count"] == 0:
01160 hwdict["count"] = 1
01161
01162
01163
01164
01165
01166
01167
01168 if os.path.exists('/sys/devices/system/cpu/cpu0/cpufreq/cpuinfo_max_freq'):
01169 hwdict['speed'] = int(file('/sys/devices/system/cpu/cpu0/cpufreq/cpuinfo_max_freq').read().strip()) / 1000
01170
01171
01172 return hwdict
01173
01174
01175
01176 def read_memory():
01177 un = os.uname()
01178 kernel = un[2]
01179 if kernel[:2] == "3.":
01180 return read_memory_2_6()
01181 if kernel[:3] == "2.6":
01182 return read_memory_2_6()
01183 if kernel[:3] == "2.4":
01184 return read_memory_2_4()
01185
01186 def read_memory_2_4():
01187 if not os.access("/proc/meminfo", os.R_OK):
01188 return {}
01189
01190 meminfo = open("/proc/meminfo", "r").read()
01191 lines = meminfo.split("\n")
01192 curline = lines[1]
01193 memlist = curline.split()
01194 memdict = {}
01195 memdict['class'] = "MEMORY"
01196 megs = int(long(memlist[1])/(1024*1024))
01197 if megs < 32:
01198 megs = megs + (4 - (megs % 4))
01199 else:
01200 megs = megs + (16 - (megs % 16))
01201 memdict['ram'] = str(megs)
01202 curline = lines[2]
01203 memlist = curline.split()
01204
01205 megs = int(long(memlist[1])/(1024*1024))
01206 memdict['swap'] = str(megs)
01207 return memdict
01208
01209 def read_memory_2_6():
01210 if not os.access("/proc/meminfo", os.R_OK):
01211 return {}
01212 meminfo = open("/proc/meminfo", "r").read()
01213 lines = meminfo.split("\n")
01214 dict = {}
01215 for line in lines:
01216 blobs = line.split(":", 1)
01217 key = blobs[0]
01218 if len(blobs) == 1:
01219 continue
01220
01221 value = blobs[1].strip()
01222 dict[key] = value
01223
01224 memdict = {}
01225 memdict["class"] = "MEMORY"
01226
01227 total_str = dict['MemTotal']
01228 blips = total_str.split(" ")
01229 total_k = long(blips[0])
01230 megs = long(total_k/(1024))
01231
01232 swap_str = dict['SwapTotal']
01233 blips = swap_str.split(' ')
01234 swap_k = long(blips[0])
01235 swap_megs = long(swap_k/(1024))
01236
01237 memdict['ram'] = str(megs)
01238 memdict['swap'] = str(swap_megs)
01239 return memdict
01240
01241
01242 def create_profile_nocatch(gate, uuid):
01243 return _HardwareProfile(gate, uuid)
01244
01245
01246
01247
01248
01249 def create_profile(gate, uuid):
01250 try:
01251 return create_profile_nocatch(gate, uuid)
01252 except SystemBusError, e:
01253 error(_('Error:') + ' ' + e.msg)
01254 if e.hint is not None:
01255 error('\t' + _('Hint:') + ' ' + e.hint)
01256 sys.exit(8)
01257
01258
01259 def get_profile_link(smoonURL, pub_uuid):
01260 return urljoin(smoonURL, '/client/show/%s' % pub_uuid)
01261
01262 def read_uuid():
01263 try:
01264 UUID = file(hw_uuid_file).read().strip()
01265 except IOError:
01266 try:
01267 UUID = file('/proc/sys/kernel/random/uuid').read().strip()
01268 try:
01269 file(hw_uuid_file, 'w').write(UUID)
01270 except Exception, e:
01271 raise UUIDError, 'Unable to save UUID to %s. Please run once as root.' % hw_uuid_file
01272 except IOError:
01273 sys.stderr.write(_('Unable to determine UUID of system!\n'))
01274 raise UUIDError, 'Could not determine UUID of system!\n'
01275 return UUID
01276
01277 def read_pub_uuid(uuiddb, uuid, user_agent=user_agent, smoonURL=smoonURL, timeout=timeout, silent=False):
01278 smoonURLparsed=urlparse(smoonURL)
01279 res = uuiddb.get_pub_uuid(uuid, smoonURLparsed[1])
01280 if res:
01281 return res
01282
01283 grabber = urlgrabber.grabber.URLGrabber(user_agent=user_agent, timeout=timeout, proxies=proxies)
01284 try:
01285 o = grabber.urlopen(urljoin(smoonURL + "/", '/client/pub_uuid/%s' % uuid))
01286 pudict = json.loads(o.read())
01287 o.close()
01288 uuiddb.set_pub_uuid(uuid, smoonURLparsed[1], pudict["pub_uuid"])
01289 return pudict["pub_uuid"]
01290 except Exception, e:
01291 if not silent:
01292 error(_('Error determining public UUID: %s') % e)
01293 sys.stderr.write(_("Unable to determine Public UUID! This could be a network error or you've\n"))
01294 sys.stderr.write(_("not submitted your profile yet.\n"))
01295 raise PubUUIDError, 'Could not determine Public UUID!\n'