MythTV  0.26-pre
smolt.py
Go to the documentation of this file.
00001 # -*- coding: utf-8 -*-
00002 
00003 # smolt - Fedora hardware profiler
00004 #
00005 # Copyright (C) 2007 Mike McGrath
00006 # Copyright (C) 2009 Sebastian Pipping <sebastian@pipping.org>
00007 #
00008 # This program is free software; you can redistribute it and/or modify
00009 # it under the terms of the GNU General Public License as published by
00010 # the Free Software Foundation; either version 2 of the License, or
00011 # (at your option) any later version.
00012 #
00013 # This program is distributed in the hope that it will be useful,
00014 # but WITHOUT ANY WARRANTY; without even the implied warranty of
00015 # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
00016 # GNU General Public License for more details.
00017 #
00018 # You should have received a copy of the GNU General Public License
00019 # along with this program; if not, write to the Free Software
00020 # Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA.
00021 
00022 ######################################################
00023 # This class is a basic wrapper for the dbus bindings
00024 #
00025 # I have completely destroyed this file, it needs some cleanup
00026 # - mmcgrath
00027 ######################################################
00028 # TODO
00029 #
00030 # Abstract "type" in device class
00031 # Find out what we're not getting
00032 #
00033 
00034 from i18n import _
00035 
00036 #import dbus
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 # Taken from the DMI spec
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             #self.systemVendor = hostInfo.get('system.vendor'
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             #hostInfo was removed with the hal restructure
00256             #if not self.systemModel:
00257                 #self.systemModel = hostInfo.get('system.hardware.product')
00258                 #if hostInfo.get('system.hardware.version'):
00259                     #self.systemModel += ' ' + hostInfo.get('system.hardware.version')
00260             #if not self.systemModel:
00261                 #self.systemModel = 'Unknown'
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         # If ctypes isn't supported (older versions of python for example)
00410         # Then just don't do anything
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 #        try:
00439 #            systemBus = dbus.SystemBus()
00440 #        except:
00441 #            raise SystemBusError, _('Could not bind to dbus.  Is dbus running?')
00442 #
00443 #        try:
00444 #            mgr = self.dbus_get_interface(systemBus, 'org.freedesktop.Hal', '/org/freedesktop/Hal/Manager', 'org.freedesktop.Hal.Manager')
00445 #            all_dev_lst = mgr.GetAllDevices()
00446 #        except:
00447 #            raise SystemBusError, _('Could not connect to hal, is it running?\nRun "service haldaemon start" as root')
00448 #
00449 #        self.systemBus = systemBus
00450 
00451         if gate.grants('devices'):
00452                 self.devices = get_device_list()
00453 #        for udi in all_dev_lst:
00454 #            props = self.get_properties_for_udi (udi)
00455 #            if udi == '/org/freedesktop/Hal/devices/computer':
00456 #                try:
00457 #                    vendor = props['system.vendor']
00458 #                    if len(vendor.strip()) == 0:
00459 #                        vendor = None
00460 #                except KeyError:
00461 #                    try:
00462 #                        vendor = props['vendor']
00463 #                        if len(vendor.strip()) == 0:
00464 #                            vendor = None
00465 #                    except KeyError:
00466 #                        vendor = None
00467 #                try:
00468 #                    product = props['system.product']
00469 #                    if len(product.strip()) == 0:
00470 #                        product = None
00471 #                except KeyError:
00472 #                    try:
00473 #                        product = props['product']
00474 #                        if len(product.strip()) == 0:
00475 #                            product = None
00476 #                    except KeyError:
00477 #                        product = None
00478 #
00479 #                # This could be done with python-dmidecode but it would pull
00480 #                # In an extra dep on smolt.  It may not be worth it
00481 #                if vendor is None or product is None:
00482 #                    try:
00483 #                        dmiOutput = subprocess.Popen('/usr/sbin/dmidecode r 2> /dev/null', shell=True, stdout=subprocess.PIPE).stdout
00484 #                    except NameError:
00485 #                        i, dmiOutput, e = os.popen('/usr/sbin/dmidecode', 'r')
00486 #                    section = None
00487 #                    sysvendor = None
00488 #                    sysproduct = None
00489 #                    boardvendor = None
00490 #                    boardproduct = None
00491 #                    for line in dmiOutput:
00492 #                        line = line.strip()
00493 #                        if "Information" in line:
00494 #                            section = line
00495 #                        elif section is None:
00496 #                            continue
00497 #                        elif line.startswith("Manufacturer: ") and section.startswith("System"):
00498 #                            sysvendor = line.split("Manufacturer: ", 1)[1]
00499 #                        elif line.startswith("Product Name: ") and section.startswith("System"):
00500 #                            sysproduct = line.split("Product Name: ", 1)[1]
00501 #                        elif line.startswith("Manufacturer: ") and section.startswith("Base Board"):
00502 #                            boardvendor = line.split("Manufacturer: ", 1)[1]
00503 #                        elif line.startswith("Product Name: ") and section.startswith("Base Board"):
00504 #                            boardproduct = line.split("Product Name: ", 1)[1]
00505 #                    status = dmiOutput.close()
00506 #                    if status is None:
00507 #                        if sysvendor not in (None, 'System Manufacturer') and sysproduct not in (None, 'System Name'):
00508 #                            props['system.vendor'] = sysvendor
00509 #                            props['system.product'] = sysproduct
00510 #                        elif boardproduct is not None and boardproduct is not None:
00511 #                            props['system.vendor'] = boardvendor
00512 #                            props['system.product'] = boardproduct
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 #    def get_properties_for_udi (self, udi):
00540 #        dev = self.dbus_get_interface(self.systemBus, 'org.freedesktop.Hal',
00541 #                                      udi, 'org.freedesktop.Hal.Device')
00542 #        return dev.GetAllProperties()
00543 
00544 #    def dbus_get_interface(self, bus, service, object, interface):
00545 #        iface = None
00546 #        # dbus-python bindings as of version 0.40.0 use new api
00547 #        if getattr(dbus, 'version', (0,0,0)) >= (0,40,0):
00548 #            # newer api: get_object(), dbus.Interface()
00549 #            proxy = bus.get_object(service, object)
00550 #            iface = dbus.Interface(proxy, interface)
00551 #        else:
00552 #            # deprecated api: get_service(), get_object()
00553 #            svc = bus.get_service(service)
00554 #            iface = svc.get_object(object, interface)
00555 #        return iface
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         #first find out the server desired protocol
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         # Log-dump submission data
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()  # Either JSON or an error page in (X)HTML
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             #Description = Description.decode('latin1')
00921             if not ignoreDevice(self.devices[device]):
00922                 yield VendorID, DeviceID, SubsysVendorID, SubsysDeviceID, Bus, Driver, Type, Description
00923 
00924 
00925 # This has got to be one of the ugliest fucntions alive
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     # This thing should return a hwdict that has the following
00940     # members:
00941     #
00942     # class, desc (required to identify the hardware device)
00943     # count, type, model, model_number, model_ver, model_rev
00944     # bogomips, platform, speed, cache
00945     hwdict = { 'class': "CPU",
00946                'desc' : "Processor",
00947                }
00948     if uname[0] == "i" and uname[-2:] == "86" or (uname == "x86_64"):
00949         # IA32 compatible enough
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 # just count the rest
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                     # XXX: make at least some effort to recover this data...
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             # damn, some machines don't report this
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         # Treat it as an an Alpha
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                 # XXX: make at least some effort to recover this data...
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']         = "" # pitty the kernel doesn't tell us this.
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         # some funky alphas actually report in the form "462375000 est."
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             # count the rest
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                     # XXX: make at least some effort to recover this data...
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             # count the rest
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                     # XXX: make at least some effort to recover this data...
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         # strings are postpended with "mhz"
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                     # XXX: make at least some effort to recover this data...
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'] = "" # pitty the kernel doesn't tell us this.
01132         speed = int(round(float(bogomips))) / 2
01133         hwdict['speed'] = speed
01134         hwdict['system'] = system
01135 
01136     else:
01137         # XXX: expand me. Be nice to others
01138         hwdict['platform']      = uname
01139         hwdict['count']         = 1 # Good as any
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     # make sure we get the right number here
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: # we have at least one
01160                 hwdict["count"] = 1
01161 
01162     # If the CPU can do frequency scaling the CPU speed returned
01163     # by /proc/cpuinfo might be less than the maximum possible for
01164     # the processor. Check sysfs for the proper file, and if it
01165     # exists, use that value.  Only use the value from CPU #0 and
01166     # assume that the rest of the CPUs are the same.
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     # This whole things hurts a lot.
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     # otherwise, it breaks on > ~4gigs of swap
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         #print blobs
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 ## For refactoring, I'll probably want to make a library
01247 ## Of command line tool functions
01248 ## This is one of them
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 ##This is another
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'
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Properties Friends