MythTV  master
smolt.py
Go to the documentation of this file.
1 # -*- coding: utf-8 -*-
2 
3 # smolt - Fedora hardware profiler
4 #
5 # Copyright (C) 2007 Mike McGrath
6 # Copyright (C) 2009 Sebastian Pipping <sebastian@pipping.org>
7 #
8 # This program is free software; you can redistribute it and/or modify
9 # it under the terms of the GNU General Public License as published by
10 # the Free Software Foundation; either version 2 of the License, or
11 # (at your option) any later version.
12 #
13 # This program is distributed in the hope that it will be useful,
14 # but WITHOUT ANY WARRANTY; without even the implied warranty of
15 # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
16 # GNU General Public License for more details.
17 #
18 # You should have received a copy of the GNU General Public License
19 # along with this program; if not, write to the Free Software
20 # Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA.
21 
22 
33 
34 from i18n import _
35 
36 #import dbus
37 import platform
38 import software
39 import commands
40 import urlgrabber.grabber
41 import sys
42 import os
43 from urlparse import urljoin
44 from urlparse import urlparse
45 from urllib import urlencode
46 import urllib
47 import json
48 from json import JSONEncoder
49 import datetime
50 import logging
51 
52 import config
53 from smolt_config import get_config_attr
54 from fs_util import get_fslist
55 from devicelist import cat
56 
57 from devicelist import get_device_list
58 import logging
59 from logging.handlers import RotatingFileHandler
60 import codecs
61 import MultipartPostHandler
62 import urllib2
63 
64 try:
65  import subprocess
66 except ImportError, e:
67  pass
68 
69 
70 WITHHELD_MAGIC_STRING = 'WITHHELD'
71 SELINUX_ENABLED = 1
72 SELINUX_DISABLED = 0
73 SELINUX_WITHHELD = -1
74 
75 
76 fs_types = get_config_attr("FS_TYPES", ["ext2", "ext3", "xfs", "reiserfs"])
77 fs_mounts = dict.fromkeys(get_config_attr("FS_MOUNTS", ["/", "/home", "/etc", "/var", "/boot"]), True)
78 fs_m_filter = get_config_attr("FS_M_FILTER", False)
79 fs_t_filter = get_config_attr("FS_T_FILTER", False)
80 
81 smoonURL = get_config_attr("SMOON_URL", "http://smolts.org/")
82 secure = get_config_attr("SECURE", 0)
83 hw_uuid_file = get_config_attr("HW_UUID", "/etc/smolt/hw-uuid")
84 admin_token_file = get_config_attr("ADMIN_TOKEN", '' )
85 
86 clientVersion = '1.3.2'
87 smoltProtocol = '0.97'
88 supported_protocols = ['0.97',]
89 user_agent = 'smolt/%s' % smoltProtocol
90 timeout = 120.0
91 proxies = None
92 DEBUG = False
93 
94 
95 PCI_BASE_CLASS_STORAGE = 1
96 PCI_CLASS_STORAGE_SCSI = 0
97 PCI_CLASS_STORAGE_IDE = 1
98 PCI_CLASS_STORAGE_FLOPPY = 2
99 PCI_CLASS_STORAGE_IPI = 3
100 PCI_CLASS_STORAGE_RAID = 4
101 PCI_CLASS_STORAGE_OTHER = 80
102 
103 PCI_BASE_CLASS_NETWORK = 2
104 PCI_CLASS_NETWORK_ETHERNET = 0
105 PCI_CLASS_NETWORK_TOKEN_RING = 1
106 PCI_CLASS_NETWORK_FDDI = 2
107 PCI_CLASS_NETWORK_ATM = 3
108 PCI_CLASS_NETWORK_OTHER = 80
109 PCI_CLASS_NETWORK_WIRELESS = 128
110 
111 PCI_BASE_CLASS_DISPLAY = 3
112 PCI_CLASS_DISPLAY_VGA = 0
113 PCI_CLASS_DISPLAY_XGA = 1
114 PCI_CLASS_DISPLAY_3D = 2
115 PCI_CLASS_DISPLAY_OTHER = 80
116 
117 PCI_BASE_CLASS_MULTIMEDIA = 4
118 PCI_CLASS_MULTIMEDIA_VIDEO = 0
119 PCI_CLASS_MULTIMEDIA_AUDIO = 1
120 PCI_CLASS_MULTIMEDIA_PHONE = 2
121 PCI_CLASS_MULTIMEDIA_HD_AUDIO = 3
122 PCI_CLASS_MULTIMEDIA_OTHER = 80
123 
124 PCI_BASE_CLASS_BRIDGE = 6
125 PCI_CLASS_BRIDGE_HOST = 0
126 PCI_CLASS_BRIDGE_ISA = 1
127 PCI_CLASS_BRIDGE_EISA = 2
128 PCI_CLASS_BRIDGE_MC = 3
129 PCI_CLASS_BRIDGE_PCI = 4
130 PCI_CLASS_BRIDGE_PCMCIA = 5
131 PCI_CLASS_BRIDGE_NUBUS = 6
132 PCI_CLASS_BRIDGE_CARDBUS = 7
133 PCI_CLASS_BRIDGE_RACEWAY = 8
134 PCI_CLASS_BRIDGE_OTHER = 80
135 
136 PCI_BASE_CLASS_COMMUNICATION = 7
137 PCI_CLASS_COMMUNICATION_SERIAL = 0
138 PCI_CLASS_COMMUNICATION_PARALLEL = 1
139 PCI_CLASS_COMMUNICATION_MULTISERIAL = 2
140 PCI_CLASS_COMMUNICATION_MODEM = 3
141 PCI_CLASS_COMMUNICATION_OTHER = 80
142 
143 PCI_BASE_CLASS_INPUT = 9
144 PCI_CLASS_INPUT_KEYBOARD = 0
145 PCI_CLASS_INPUT_PEN = 1
146 PCI_CLASS_INPUT_MOUSE = 2
147 PCI_CLASS_INPUT_SCANNER = 3
148 PCI_CLASS_INPUT_GAMEPORT = 4
149 PCI_CLASS_INPUT_OTHER = 80
150 
151 PCI_BASE_CLASS_SERIAL = 12
152 PCI_CLASS_SERIAL_FIREWIRE = 0
153 PCI_CLASS_SERIAL_ACCESS = 1
154 
155 PCI_CLASS_SERIAL_SSA = 2
156 PCI_CLASS_SERIAL_USB = 3
157 PCI_CLASS_SERIAL_FIBER = 4
158 PCI_CLASS_SERIAL_SMBUS = 5
159 
160 
161 # Taken from the DMI spec
162 FORMFACTOR_LIST = [ "Unknown",
163  "Other",
164  "Unknown",
165  "Desktop",
166  "Low Profile Desktop",
167  "Pizza Box",
168  "Mini Tower",
169  "Tower",
170  "Portable",
171  "Laptop",
172  "Notebook",
173  "Hand Held",
174  "Docking Station",
175  "All In One",
176  "Sub Notebook",
177  "Space-saving",
178  "Lunch Box",
179  "Main Server Chassis",
180  "Expansion Chassis",
181  "Sub Chassis",
182  "Bus Expansion Chassis",
183  "Peripheral Chassis",
184  "RAID Chassis",
185  "Rack Mount Chassis",
186  "Sealed-case PC",
187  "Multi-system",
188  "CompactPCI",
189  "AdvancedTCA"
190  ]
191 
192 def to_ascii(o, current_encoding='utf-8'):
193  if not isinstance(o, basestring):
194  return o
195 
196  if isinstance(o, unicode):
197  s = o
198  else:
199  s = unicode(o, current_encoding)
200  return s
201 
202 
203 class Host:
204  def __init__(self, gate, uuid):
205  cpuInfo = read_cpuinfo()
206  memory = read_memory()
207  self.UUID = uuid
208  self.os = gate.process('distro', software.read_os(), WITHHELD_MAGIC_STRING)
209  self.defaultRunlevel = gate.process('run_level', software.read_runlevel(), -1)
210 
211  self.bogomips = gate.process('cpu', cpuInfo.get('bogomips', 0), 0)
212  self.cpuVendor = gate.process('cpu', cpuInfo.get('type', ''), WITHHELD_MAGIC_STRING)
213  self.cpuModel = gate.process('cpu', cpuInfo.get('model', ''), WITHHELD_MAGIC_STRING)
214  self.cpu_stepping = gate.process('cpu', cpuInfo.get('cpu_stepping', 0), 0)
215  self.cpu_family = gate.process('cpu', cpuInfo.get('cpu_family', ''), '')
216  self.cpu_model_num = gate.process('cpu', cpuInfo.get('cpu_model_num', 0), 0)
217  self.numCpus = gate.process('cpu', cpuInfo.get('count', 0), 0)
218  self.cpuSpeed = gate.process('cpu', cpuInfo.get('speed', 0), 0)
219 
220  self.systemMemory = gate.process('ram_size', memory['ram'], 0)
221  self.systemSwap = gate.process('swap_size', memory['swap'], 0)
222  self.kernelVersion = gate.process('kernel', os.uname()[2], WITHHELD_MAGIC_STRING)
223  if gate.grants('language'):
224  try:
225  self.language = os.environ['LANG']
226  except KeyError:
227  try:
228  status, lang = commands.getstatusoutput("grep LANG /etc/sysconfig/i18n")
229  if status == 0:
230  self.language = lang.split('"')[1]
231  else:
232  self.language = 'Unknown'
233  except:
234  self.language = 'Unknown'
235  else:
236  self.language = WITHHELD_MAGIC_STRING
237 
238  tempform = platform.machine()
239  self.platform = gate.process('arch', tempform, WITHHELD_MAGIC_STRING)
240 
241  if gate.grants('vendor'):
242  #self.systemVendor = hostInfo.get('system.vendor'
243  try:
244  self.systemVendor = cat('/sys/devices/virtual/dmi/id/sys_vendor')[0].strip()
245  except:
246  self.systemVendor = 'Unknown'
247  else:
248  self.systemVendor = WITHHELD_MAGIC_STRING
249 
250  if gate.grants('model'):
251  try:
252  self.systemModel = cat('/sys/devices/virtual/dmi/id/product_name')[0].strip() + ' ' + cat('/sys/devices/virtual/dmi/id/product_version')[0].strip()
253  except:
254  self.systemModel = 'Unknown'
255  #hostInfo was removed with the hal restructure
256  #if not self.systemModel:
257  #self.systemModel = hostInfo.get('system.hardware.product')
258  #if hostInfo.get('system.hardware.version'):
259  #self.systemModel += ' ' + hostInfo.get('system.hardware.version')
260  #if not self.systemModel:
261  #self.systemModel = 'Unknown'
262  else:
263  self.systemModel = WITHHELD_MAGIC_STRING
264 
265  if gate.grants('form_factor'):
266  try:
267  formfactor_id = int(cat('/sys/devices/virtual/dmi/id/chassis_type')[0].strip())
268  self.formfactor = FORMFACTOR_LIST[formfactor_id]
269  except:
270  self.formfactor = 'Unknown'
271  else:
272  self.formfactor = WITHHELD_MAGIC_STRING
273 
274  if tempform == 'ppc64':
275  if hostInfo.get('openfirmware.model'):
276  if hostInfo['openfirmware.model'][:3] == 'IBM':
277  self.systemVendor = 'IBM'
278  model = hostInfo['openfirmware.model'][4:8]
279 
280  model_map = {
281  '8842':'JS20',
282  '6779':'JS21',
283  '6778':'JS21',
284  '7988':'JS21',
285  '8844':'JS21',
286  '0200':'QS20',
287  '0792':'QS21',
288  }
289  try:
290  model_name = model_map[model]
291  self.systemModel = gate.process('model', model_name)
292  self.formfactor = gate.process('form_factor', 'Blade')
293  except KeyError:
294  pass
295 
296  if gate.grants('selinux'):
297  try:
298  import selinux
299  try:
300  if selinux.is_selinux_enabled() == 1:
301  self.selinux_enabled = SELINUX_ENABLED
302  else:
303  self.selinux_enabled = SELINUX_DISABLED
304  except:
305  self.selinux_enabled = SELINUX_DISABLED
306  try:
307  self.selinux_policy = selinux.selinux_getpolicytype()[1]
308  except:
309  self.selinux_policy = "Unknown"
310  try:
311  enforce = selinux.security_getenforce()
312  if enforce == 0:
313  self.selinux_enforce = "Permissive"
314  elif enforce == 1:
315  self.selinux_enforce = "Enforcing"
316  elif enforce == -1:
317  self.selinux_enforce = "Disabled"
318  else:
319  self.selinux_enforce = "FUBARD"
320  except:
321  self.selinux_enforce = "Unknown"
322  except ImportError:
323  self.selinux_enabled = SELINUX_DISABLED
324  self.selinux_policy = "Not Installed"
325  self.selinux_enforce = "Not Installed"
326  else:
327  self.selinux_enabled = SELINUX_WITHHELD
328  self.selinux_policy = WITHHELD_MAGIC_STRING
329  self.selinux_enforce = WITHHELD_MAGIC_STRING
330 
331 
333  if not gate.grants('file_systems'):
334  return []
335 
336  if fs_t_filter:
337  file_systems = [fs for fs in get_fslist() if fs.fs_type in fs_types]
338  else:
339  file_systems = get_fslist()
340 
341  file_systems = [fs for fs in file_systems if fs.mnt_dev.startswith('/dev/')]
342 
343  if fs_m_filter:
344  for fs in file_systems:
345  if not fs.mnt_pnt in fs_mounts:
346  fs.mnt_pnt = WITHHELD_MAGIC_STRING
347  else:
348  for fs in file_systems:
349  fs.mnt_pnt = WITHHELD_MAGIC_STRING
350 
351  return file_systems
352 
353 def ignoreDevice(device):
354  ignore = 1
355  if device.bus == 'Unknown' or device.bus == 'unknown':
356  return 1
357  if device.vendorid in (0, None) and device.type == None:
358  return 1
359  if device.bus == 'usb' and device.driver == 'hub':
360  return 1
361  if device.bus == 'usb' and 'Hub' in device.description:
362  return 1
363  if device.bus == 'sound' and device.driver == 'Unknown':
364  return 1
365  if device.bus == 'pnp' and device.driver in ('Unknown', 'system'):
366  return 1
367  if device.bus == 'block' and device.type == 'DISK':
368  return 1
369  if device.bus == 'usb_device' and device.type == None:
370  return 1
371  return 0
372 
373 class ServerError(Exception):
374  def __init__(self, value):
375  self.value = value
376  def __str__(self):
377  return repr(self.value)
378 
379 def serverMessage(page):
380  for line in page.split("\n"):
381  if 'UUID:' in line:
382  return line.strip()[6:]
383  if 'ServerMessage:' in line:
384  if 'Critical' in line:
385  raise ServerError, line.split('ServerMessage: ')[1]
386  else:
387  print _('Server Message: "%s"') % line.split('ServerMessage: ')[1]
388 
389 def error(message):
390  print >> sys.stderr, message
391 
392 def debug(message):
393  if DEBUG:
394  print message
395 
397  '''Attempt to reset the system hostname resolver.
398  returns 0 on success, or -1 if an error occurs.'''
399  try:
400  import ctypes
401  try:
402  resolv = ctypes.CDLL("libresolv.so.2")
403  r = resolv.__res_init()
404  except (OSError, AttributeError):
405  print "Warning: could not find __res_init in libresolv.so.2"
406  r = -1
407  return r
408  except ImportError:
409  # If ctypes isn't supported (older versions of python for example)
410  # Then just don't do anything
411  pass
412 
413 class SystemBusError(Exception):
414  def __init__(self, message, hint = None):
415  self.msg = message
416  self.hint = hint
417 
418  def __str__(self):
419  return str(self.msg)
420 
421 class UUIDError(Exception):
422  def __init__(self, message):
423  self.msg = message
424 
425  def __str__(self):
426  return str(self.msg)
427 
428 class PubUUIDError(Exception):
429  def __init__(self, message):
430  self.msg = message
431 
432  def __str__(self):
433  return str(self.msg)
434 
436  devices = {}
437  def __init__(self, gate, uuid):
438 # try:
439 # systemBus = dbus.SystemBus()
440 # except:
441 # raise SystemBusError, _('Could not bind to dbus. Is dbus running?')
442 #
443 # try:
444 # mgr = self.dbus_get_interface(systemBus, 'org.freedesktop.Hal', '/org/freedesktop/Hal/Manager', 'org.freedesktop.Hal.Manager')
445 # all_dev_lst = mgr.GetAllDevices()
446 # except:
447 # raise SystemBusError, _('Could not connect to hal, is it running?\nRun "service haldaemon start" as root')
448 #
449 # self.systemBus = systemBus
450 
451  if gate.grants('devices'):
453 # for udi in all_dev_lst:
454 # props = self.get_properties_for_udi (udi)
455 # if udi == '/org/freedesktop/Hal/devices/computer':
456 # try:
457 # vendor = props['system.vendor']
458 # if len(vendor.strip()) == 0:
459 # vendor = None
460 # except KeyError:
461 # try:
462 # vendor = props['vendor']
463 # if len(vendor.strip()) == 0:
464 # vendor = None
465 # except KeyError:
466 # vendor = None
467 # try:
468 # product = props['system.product']
469 # if len(product.strip()) == 0:
470 # product = None
471 # except KeyError:
472 # try:
473 # product = props['product']
474 # if len(product.strip()) == 0:
475 # product = None
476 # except KeyError:
477 # product = None
478 #
479 # # This could be done with python-dmidecode but it would pull
480 # # In an extra dep on smolt. It may not be worth it
481 # if vendor is None or product is None:
482 # try:
483 # dmiOutput = subprocess.Popen('/usr/sbin/dmidecode r 2> /dev/null', shell=True, stdout=subprocess.PIPE).stdout
484 # except NameError:
485 # i, dmiOutput, e = os.popen('/usr/sbin/dmidecode', 'r')
486 # section = None
487 # sysvendor = None
488 # sysproduct = None
489 # boardvendor = None
490 # boardproduct = None
491 # for line in dmiOutput:
492 # line = line.strip()
493 # if "Information" in line:
494 # section = line
495 # elif section is None:
496 # continue
497 # elif line.startswith("Manufacturer: ") and section.startswith("System"):
498 # sysvendor = line.split("Manufacturer: ", 1)[1]
499 # elif line.startswith("Product Name: ") and section.startswith("System"):
500 # sysproduct = line.split("Product Name: ", 1)[1]
501 # elif line.startswith("Manufacturer: ") and section.startswith("Base Board"):
502 # boardvendor = line.split("Manufacturer: ", 1)[1]
503 # elif line.startswith("Product Name: ") and section.startswith("Base Board"):
504 # boardproduct = line.split("Product Name: ", 1)[1]
505 # status = dmiOutput.close()
506 # if status is None:
507 # if sysvendor not in (None, 'System Manufacturer') and sysproduct not in (None, 'System Name'):
508 # props['system.vendor'] = sysvendor
509 # props['system.product'] = sysproduct
510 # elif boardproduct is not None and boardproduct is not None:
511 # props['system.vendor'] = boardvendor
512 # props['system.product'] = boardproduct
513  self.host = Host(gate, uuid)
514 
515  self.fss = get_file_systems(gate)
516 
518 
519  def get_distro_specific_data(self, gate):
520  dist_dict = {}
521  try:
522  import distros.all
523  except:
524  return dist_dict
525 
526  for d in distros.all.get():
527  key = d.key()
528  if d.detected():
529  logging.info('Distro "%s" detected' % (key))
530  d.gather(gate, debug=True)
531  dist_dict[key] = {
532  'data':d.data(),
533  'html':d.html(),
534  'rst':d.rst(),
535  'rst_excerpt':d.rst_excerpt(),
536  }
537  return dist_dict
538 
539 # def get_properties_for_udi (self, udi):
540 # dev = self.dbus_get_interface(self.systemBus, 'org.freedesktop.Hal',
541 # udi, 'org.freedesktop.Hal.Device')
542 # return dev.GetAllProperties()
543 
544 # def dbus_get_interface(self, bus, service, object, interface):
545 # iface = None
546 # # dbus-python bindings as of version 0.40.0 use new api
547 # if getattr(dbus, 'version', (0,0,0)) >= (0,40,0):
548 # # newer api: get_object(), dbus.Interface()
549 # proxy = bus.get_object(service, object)
550 # iface = dbus.Interface(proxy, interface)
551 # else:
552 # # deprecated api: get_service(), get_object()
553 # svc = bus.get_service(service)
554 # iface = svc.get_object(object, interface)
555 # return iface
556 
557  def get_sendable_devices(self, protocol_version=smoltProtocol):
558  my_devices = []
559  for device in self.devices:
560  try:
561  Bus = self.devices[device].bus
562  VendorID = self.devices[device].vendorid
563  DeviceID = self.devices[device].deviceid
564  SubsysVendorID = self.devices[device].subsysvendorid
565  SubsysDeviceID = self.devices[device].subsysdeviceid
566  Driver = self.devices[device].driver
567  Type = self.devices[device].type
568  Description = self.devices[device].description
569  except:
570  continue
571  else:
572  if not ignoreDevice(self.devices[device]):
573  my_devices.append({"vendor_id": VendorID,
574  "device_id": DeviceID,
575  "subsys_vendor_id": SubsysVendorID,
576  "subsys_device_id": SubsysDeviceID,
577  "bus": Bus,
578  "driver": Driver,
579  "type": Type,
580  "description": Description})
581 
582  return my_devices
583 
584  def get_sendable_host(self, protocol_version=smoltProtocol):
585  return {'uuid' : self.host.UUID,
586  'os' : self.host.os,
587  'default_runlevel': self.host.defaultRunlevel,
588  'language' : self.host.language,
589  'platform' : self.host.platform,
590  'bogomips' : self.host.bogomips,
591  'cpu_vendor' : self.host.cpuVendor,
592  'cpu_model' : self.host.cpuModel,
593  'cpu_stepping' : self.host.cpu_stepping,
594  'cpu_family' : self.host.cpu_family,
595  'cpu_model_num' : self.host.cpu_model_num,
596  'num_cpus': self.host.numCpus,
597  'cpu_speed' : self.host.cpuSpeed,
598  'system_memory' : self.host.systemMemory,
599  'system_swap' : self.host.systemSwap,
600  'vendor' : self.host.systemVendor,
601  'system' : self.host.systemModel,
602  'kernel_version' : self.host.kernelVersion,
603  'formfactor' : self.host.formfactor,
604  'selinux_enabled': self.host.selinux_enabled,
605  'selinux_policy': self.host.selinux_policy,
606  'selinux_enforce': self.host.selinux_enforce
607  }
608 
609  def get_sendable_fss(self, protocol_version=smoltProtocol):
610  return [fs.to_dict() for fs in self.fss]
611 
612  def write_pub_uuid(self, uuiddb, smoonURL, pub_uuid, uuid):
613  smoonURLparsed=urlparse(smoonURL)
614  if pub_uuid is None:
615  return
616 
617  try:
618  uuiddb.set_pub_uuid(uuid, smoonURLparsed[1], pub_uuid)
619  except Exception, e:
620  sys.stderr.write(_('\tYour pub_uuid could not be written.\n\n'))
621  return
622 
623  def write_admin_token(self,smoonURL,admin,admin_token_file):
624  smoonURLparsed=urlparse(smoonURL)
625  admin_token_file += ("-"+smoonURLparsed[1])
626  try:
627  file(admin_token_file, 'w').write(admin)
628  except Exception, e:
629  sys.stderr.write(_('\tYour admin token could not be cached: %s\n' % e))
630  return
631 
632  def get_submission_data(self, prefered_protocol=None):
633  send_host_obj = self.get_sendable_host(prefered_protocol)
634  send_host_obj['devices'] = self.get_sendable_devices(prefered_protocol)
635  send_host_obj['fss'] = self.get_sendable_fss(prefered_protocol)
636  send_host_obj['smolt_protocol'] = prefered_protocol
637 
638  dist_data_dict = {}
639  for k, v in self.distro_specific.items():
640  dist_data_dict[k] = v['data']
641  send_host_obj['distro_specific'] = dist_data_dict
642 
643  return send_host_obj
644 
646  lines = []
647  if not self.distro_specific:
648  lines.append(_('No distribution-specific data yet'))
649  else:
650  for k, v in self.distro_specific.items():
651  lines.append(v['html'])
652  return '\n'.join(lines)
653 
654  def send(self, uuiddb, uuid, user_agent=user_agent, smoonURL=smoonURL, timeout=timeout, proxies=proxies, batch=False):
655  def serialize(object, human=False):
656  if human:
657  indent = 2
658  sort_keys = True
659  else:
660  indent = None
661  sort_keys = False
662  return JSONEncoder(indent=indent, sort_keys=sort_keys).encode(object)
663 
665  grabber = urlgrabber.grabber.URLGrabber(user_agent=user_agent, timeout=timeout, proxies=proxies)
666  #first find out the server desired protocol
667  try:
668  token = grabber.urlopen(urljoin(smoonURL + "/", '/tokens/token_json?uuid=%s' % self.host.UUID, False))
669  except urlgrabber.grabber.URLGrabError, e:
670  error(_('Error contacting Server: %s') % e)
671  return (1, None, None)
672  tok_str = token.read()
673  try:
674  try:
675  tok_obj = json.loads(tok_str)
676  if tok_obj['prefered_protocol'] in supported_protocols:
677  prefered_protocol = tok_obj['prefered_protocol']
678  else:
679  error(_('Wrong version, server incapable of handling your client'))
680  return (1, None, None)
681  tok = tok_obj['token']
682 
683  except ValueError, e:
684  error(_('Something went wrong fetching a token'))
685  finally:
686  token.close()
687 
688  send_host_obj = self.get_submission_data(prefered_protocol)
689 
690 
691  debug('smoon server URL: %s' % smoonURL)
692 
693  serialized_host_obj_machine = serialize(send_host_obj, human=False)
694 
695  # Log-dump submission data
696  log_matrix = {
697  '.json':serialize(send_host_obj, human=True),
698  '-distro.html':self.get_distro_specific_html(),
699  '.rst':'\n'.join(map(to_ascii, self.getProfile())),
700  }
701  logdir = os.path.expanduser('~/.smolt/')
702  try:
703  if not os.path.exists(logdir):
704  os.mkdir(logdir, 0700)
705 
706  for k, v in log_matrix.items():
707  filename = os.path.expanduser(os.path.join(
708  logdir, 'submission%s' % k))
709  r = RotatingFileHandler(filename, \
710  maxBytes=1000000, backupCount=9)
711  r.stream.write(v)
712  r.doRollover()
713  r.close()
714  os.remove(filename)
715  except:
716  pass
717  del logdir
718  del log_matrix
719 
720 
721  debug('sendHostStr: %s' % serialized_host_obj_machine)
722  debug('Sending Host')
723 
724  if batch:
725  entry_point = "/client/batch_add_json"
726  logging.debug('Submitting in asynchronous mode')
727  else:
728  entry_point = "/client/add_json"
729  logging.debug('Submitting in synchronous mode')
730  request_url = urljoin(smoonURL + "/", entry_point, False)
731  logging.debug('Sending request to %s' % request_url)
732  try:
733  opener = urllib2.build_opener(MultipartPostHandler.MultipartPostHandler)
734  params = { 'uuid':self.host.UUID,
735  'host':serialized_host_obj_machine,
736  'token':tok,
737  'smolt_protocol':smoltProtocol}
738  o = opener.open(request_url, params)
739 
740  except Exception, e:
741  error(_('Error contacting Server: %s') % e)
742  return (1, None, None)
743  else:
744  try:
745  server_response = serverMessage(o.read())
746  except ServerError, e:
747  error(_('Error contacting server: %s') % e)
748  return (1, None, None)
749 
750  o.close()
751  if batch:
752  pub_uuid = None
753  else:
754  pub_uuid = server_response
755  self.write_pub_uuid(uuiddb, smoonURL, pub_uuid, uuid)
756 
757  try:
758  admin_token = grabber.urlopen(urljoin(smoonURL + "/", '/tokens/admin_token_json?uuid=%s' % self.host.UUID, False))
759  except urlgrabber.grabber.URLGrabError, e:
760  error(_('An error has occured while contacting the server: %s' % e))
761  sys.exit(1)
762  admin_str = admin_token.read()
763  admin_obj = json.loads(admin_str)
764  if admin_obj['prefered_protocol'] in supported_protocols:
765  prefered_protocol = admin_obj['prefered_protocol']
766  else:
767  error(_('Wrong version, server incapable of handling your client'))
768  return (1, None, None)
769  admin = admin_obj['token']
770 
771  if not admin_token_file == '' :
772  self.write_admin_token(smoonURL,admin,admin_token_file)
773  return (0, pub_uuid, admin)
774 
775  def regenerate_pub_uuid(self, uuiddb, uuid, user_agent=user_agent, smoonURL=smoonURL, timeout=timeout):
776  grabber = urlgrabber.grabber.URLGrabber(user_agent=user_agent, timeout=timeout)
777  try:
778  new_uuid = grabber.urlopen(urljoin(smoonURL + "/", '/client/regenerate_pub_uuid?uuid=%s' % self.host.UUID))
779  except urlgrabber.grabber.URLGrabError, e:
780  raise ServerError, str(e)
781 
782  response = new_uuid.read() # Either JSON or an error page in (X)HTML
783  try:
784  response_dict = json.loads(response)
785  except Exception, e:
786  serverMessage(response)
787  raise ServerError, _('Reply from server could not be interpreted')
788  else:
789  try:
790  pub_uuid = response_dict['pub_uuid']
791  except KeyError:
792  raise ServerError, _('Reply from server could not be interpreted')
793  self.write_pub_uuid(uuiddb, smoonURL, pub_uuid, uuid)
794  return pub_uuid
795 
796 
798  d = {
799  _('OS'):self.host.os,
800  _('Default run level'):self.host.defaultRunlevel,
801  _('Language'):self.host.language,
802  }
803  lines = []
804  for k, v in d.items():
805  lines.append('%s: %s' % (k, v))
806  lines.append('...')
807  return '\n'.join(lines)
808 
810  lines = []
811  for i, (VendorID, DeviceID, SubsysVendorID, SubsysDeviceID, Bus, Driver, Type, Description) \
812  in enumerate(self.deviceIter()):
813  if i == 3:
814  break
815  lines.append('(%s:%s:%s:%s) %s, %s, %s, %s' % (VendorID, DeviceID, SubsysVendorID, \
816  SubsysDeviceID, Bus, Driver, Type, Description))
817  lines.append('...')
818  return '\n'.join(lines)
819 
821  lines = []
822  lines.append('device mtpt type bsize frsize blocks bfree bavail file ffree favail')
823  for i, v in enumerate(self.fss):
824  if i == 2:
825  break
826  lines.append(str(v))
827  lines.append('...')
828  return '\n'.join(lines)
829 
831  for k, v in self.distro_specific.items():
832  return v['rst_excerpt']
833  return "No data, yet"
834 
835  def getProfile(self):
836  printBuffer = []
837 
838  printBuffer.append('# ' + _('This is a Smolt report shown within your default pager.'))
839  printBuffer.append('# ' + _('Below you can see what data you will submit to the server.'))
840  printBuffer.append('# ' + _('To get back to Smolt exit the pager (try hitting "q").'))
841  printBuffer.append('#')
842  printBuffer.append('# ' + _('NOTE: Editing this file does not change the data submitted.'))
843  printBuffer.append('')
844  printBuffer.append('')
845 
846  printBuffer.append(_('General'))
847  printBuffer.append('=================================')
848  for label, data in self.hostIter():
849  try:
850  printBuffer.append('%s: %s' % (label, data))
851  except UnicodeDecodeError:
852  try:
853  printBuffer.append('%s: %s' % (unicode(label, 'utf-8'), data))
854  except UnicodeDecodeError:
855  printBuffer.append('%r: %r' % (label, data))
856 
857  if self.devices:
858  printBuffer.append('')
859  printBuffer.append('')
860  printBuffer.append(_('Devices'))
861  printBuffer.append('=================================')
862 
863  for VendorID, DeviceID, SubsysVendorID, SubsysDeviceID, Bus, Driver, Type, Description in self.deviceIter():
864  printBuffer.append('(%s:%s:%s:%s) %s, %s, %s, %s' % (VendorID, DeviceID, SubsysVendorID, SubsysDeviceID, Bus, Driver, Type, Description))
865 
866  printBuffer.append('')
867  printBuffer.append('')
868  printBuffer.append(_('Filesystem Information'))
869  printBuffer.append('=================================')
870  printBuffer.append('device mtpt type bsize frsize blocks bfree bavail file ffree favail')
871  printBuffer.append('-------------------------------------------------------------------')
872  for fs in self.fss:
873  printBuffer.append(str(fs))
874 
875  for k, v in self.distro_specific.items():
876  printBuffer.append('')
877  printBuffer.append('')
878  printBuffer.append(v['rst'])
879 
880  printBuffer.append('')
881  return printBuffer
882 
883 
884  def hostIter(self):
885  '''Iterate over host information.'''
886  yield _('UUID'), self.host.UUID
887  yield _('OS'), self.host.os
888  yield _('Default run level'), self.host.defaultRunlevel
889  yield _('Language'), self.host.language
890  yield _('Platform'), self.host.platform
891  yield _('BogoMIPS'), self.host.bogomips
892  yield _('CPU Vendor'), self.host.cpuVendor
893  yield _('CPU Model'), self.host.cpuModel
894  yield _('CPU Stepping'), self.host.cpu_stepping
895  yield _('CPU Family'), self.host.cpu_family
896  yield _('CPU Model Num'), self.host.cpu_model_num
897  yield _('Number of CPUs'), self.host.numCpus
898  yield _('CPU Speed'), self.host.cpuSpeed
899  yield _('System Memory'), self.host.systemMemory
900  yield _('System Swap'), self.host.systemSwap
901  yield _('Vendor'), self.host.systemVendor
902  yield _('System'), self.host.systemModel
903  yield _('Form factor'), self.host.formfactor
904  yield _('Kernel'), self.host.kernelVersion
905  yield _('SELinux Enabled'), self.host.selinux_enabled
906  yield _('SELinux Policy'), self.host.selinux_policy
907  yield _('SELinux Enforce'), self.host.selinux_enforce
908 
909  def deviceIter(self):
910  '''Iterate over our devices.'''
911  for device in self.devices:
912  Bus = self.devices[device].bus
913  VendorID = self.devices[device].vendorid
914  DeviceID = self.devices[device].deviceid
915  SubsysVendorID = self.devices[device].subsysvendorid
916  SubsysDeviceID = self.devices[device].subsysdeviceid
917  Driver = self.devices[device].driver
918  Type = self.devices[device].type
919  Description = self.devices[device].description
920  #Description = Description.decode('latin1')
921  if not ignoreDevice(self.devices[device]):
922  yield VendorID, DeviceID, SubsysVendorID, SubsysDeviceID, Bus, Driver, Type, Description
923 
924 
925 # This has got to be one of the ugliest fucntions alive
927  def get_entry(a, entry):
928  e = entry.lower()
929  if not a.has_key(e):
930  return ""
931  return a[e]
932 
933  if not os.access("/proc/cpuinfo", os.R_OK):
934  return {}
935 
936  cpulist = open("/proc/cpuinfo", "r").read()
937  uname = os.uname()[4].lower()
938 
939  # This thing should return a hwdict that has the following
940  # members:
941  #
942  # class, desc (required to identify the hardware device)
943  # count, type, model, model_number, model_ver, model_rev
944  # bogomips, platform, speed, cache
945  hwdict = { 'class': "CPU",
946  'desc' : "Processor",
947  }
948  if uname[0] == "i" and uname[-2:] == "86" or (uname == "x86_64"):
949  # IA32 compatible enough
950  count = 0
951  tmpdict = {}
952  for cpu in cpulist.split("\n\n"):
953  if not len(cpu):
954  continue
955  count = count + 1
956  if count > 1:
957  continue # just count the rest
958  for cpu_attr in cpu.split("\n"):
959  if not len(cpu_attr):
960  continue
961  vals = cpu_attr.split(':')
962  if len(vals) != 2:
963  # XXX: make at least some effort to recover this data...
964  continue
965  name, value = vals[0].strip(), vals[1].strip()
966  tmpdict[name.lower()] = value
967 
968  if uname == "x86_64":
969  hwdict['platform'] = 'x86_64'
970  else:
971  hwdict['platform'] = "i386"
972 
973  hwdict['count'] = count
974  hwdict['type'] = get_entry(tmpdict, 'vendor_id')
975  hwdict['model'] = get_entry(tmpdict, 'model name')
976  hwdict['model_number'] = get_entry(tmpdict, 'cpu family')
977  hwdict['model_ver'] = get_entry(tmpdict, 'model')
978  hwdict['cpu_stepping'] = get_entry(tmpdict, 'stepping')
979  hwdict['cpu_family'] = get_entry(tmpdict, 'cpu family')
980  hwdict['cpu_model_num'] = get_entry(tmpdict, 'model')
981  hwdict['cache'] = get_entry(tmpdict, 'cache size')
982  hwdict['bogomips'] = get_entry(tmpdict, 'bogomips')
983  hwdict['other'] = get_entry(tmpdict, 'flags')
984  mhz_speed = get_entry(tmpdict, 'cpu mhz')
985  if mhz_speed == "":
986  # damn, some machines don't report this
987  mhz_speed = "-1"
988  try:
989  hwdict['speed'] = int(round(float(mhz_speed)) - 1)
990  except ValueError:
991  hwdict['speed'] = -1
992 
993 
994  elif uname in["alpha", "alphaev6"]:
995  # Treat it as an an Alpha
996  tmpdict = {}
997  for cpu_attr in cpulist.split("\n"):
998  if not len(cpu_attr):
999  continue
1000  vals = cpu_attr.split(':')
1001  if len(vals) != 2:
1002  # XXX: make at least some effort to recover this data...
1003  continue
1004  name, value = vals[0].strip(), vals[1].strip()
1005  tmpdict[name.lower()] = value.lower()
1006 
1007  hwdict['platform'] = "alpha"
1008  hwdict['count'] = get_entry(tmpdict, 'cpus detected')
1009  hwdict['type'] = get_entry(tmpdict, 'cpu')
1010  hwdict['model'] = get_entry(tmpdict, 'cpu model')
1011  hwdict['model_number'] = get_entry(tmpdict, 'cpu variation')
1012  hwdict['model_version'] = "%s/%s" % (get_entry(tmpdict, 'system type'),
1013  get_entry(tmpdict,'system variation'))
1014  hwdict['model_rev'] = get_entry(tmpdict, 'cpu revision')
1015  hwdict['cache'] = "" # pitty the kernel doesn't tell us this.
1016  hwdict['bogomips'] = get_entry(tmpdict, 'bogomips')
1017  hwdict['other'] = get_entry(tmpdict, 'platform string')
1018  hz_speed = get_entry(tmpdict, 'cycle frequency [Hz]')
1019  # some funky alphas actually report in the form "462375000 est."
1020  hz_speed = hz_speed.split()
1021  try:
1022  hwdict['speed'] = int(round(float(hz_speed[0]))) / 1000000
1023  except ValueError:
1024  hwdict['speed'] = -1
1025 
1026  elif uname in ["ia64"]:
1027  tmpdict = {}
1028  count = 0
1029  for cpu in cpulist.split("\n\n"):
1030  if not len(cpu):
1031  continue
1032  count = count + 1
1033  # count the rest
1034  if count > 1:
1035  continue
1036  for cpu_attr in cpu.split("\n"):
1037  if not len(cpu_attr):
1038  continue
1039  vals = cpu_attr.split(":")
1040  if len(vals) != 2:
1041  # XXX: make at least some effort to recover this data...
1042  continue
1043  name, value = vals[0].strip(), vals[1].strip()
1044  tmpdict[name.lower()] = value.lower()
1045 
1046  hwdict['platform'] = uname
1047  hwdict['count'] = count
1048  hwdict['type'] = get_entry(tmpdict, 'vendor')
1049  hwdict['model'] = get_entry(tmpdict, 'family')
1050  hwdict['model_ver'] = get_entry(tmpdict, 'archrev')
1051  hwdict['model_rev'] = get_entry(tmpdict, 'revision')
1052  hwdict['bogomips'] = get_entry(tmpdict, 'bogomips')
1053  mhz_speed = tmpdict['cpu mhz']
1054  try:
1055  hwdict['speed'] = int(round(float(mhz_speed)) - 1)
1056  except ValueError:
1057  hwdict['speed'] = -1
1058  hwdict['other'] = get_entry(tmpdict, 'features')
1059 
1060  elif uname in ['ppc64','ppc']:
1061  tmpdict = {}
1062  count = 0
1063  for cpu in cpulist.split("processor"):
1064  if not len(cpu):
1065  continue
1066  count = count + 1
1067  # count the rest
1068  if count > 1:
1069  continue
1070  for cpu_attr in cpu.split("\n"):
1071  if not len(cpu_attr):
1072  continue
1073  vals = cpu_attr.split(":")
1074  if len(vals) != 2:
1075  # XXX: make at least some effort to recover this data...
1076  continue
1077  name, value = vals[0].strip(), vals[1].strip()
1078  tmpdict[name.lower()] = value.lower()
1079 
1080  hwdict['platform'] = uname
1081  hwdict['count'] = count
1082  hwdict['model'] = get_entry(tmpdict, "cpu")
1083  hwdict['model_ver'] = get_entry(tmpdict, 'revision')
1084  hwdict['bogomips'] = get_entry(tmpdict, 'bogomips')
1085  hwdict['vendor'] = get_entry(tmpdict, 'machine')
1086  if get_entry(tmpdict, 'cpu').startswith('ppc970'):
1087  hwdict['type'] = 'IBM'
1088  else:
1089  hwdict['type'] = get_entry(tmpdict, 'platform')
1090  hwdict['system'] = get_entry(tmpdict, 'detected as')
1091  # strings are postpended with "mhz"
1092  mhz_speed = get_entry(tmpdict, 'clock')[:-3]
1093  try:
1094  hwdict['speed'] = int(round(float(mhz_speed)) - 1)
1095  except ValueError:
1096  hwdict['speed'] = -1
1097 
1098  elif uname in ["sparc64","sparc"]:
1099  tmpdict = {}
1100  bogomips = 0
1101  for cpu in cpulist.split("\n\n"):
1102  if not len(cpu):
1103  continue
1104 
1105  for cpu_attr in cpu.split("\n"):
1106  if not len(cpu_attr):
1107  continue
1108  vals = cpu_attr.split(":")
1109  if len(vals) != 2:
1110  # XXX: make at least some effort to recover this data...
1111  continue
1112  name, value = vals[0].strip(), vals[1].strip()
1113  if name.endswith('Bogo'):
1114  if bogomips == 0:
1115  bogomips = int(round(float(value)) )
1116  continue
1117  continue
1118  tmpdict[name.lower()] = value.lower()
1119  system = ''
1120  if not os.access("/proc/openprom/banner-name", os.R_OK):
1121  system = 'Unknown'
1122  if os.access("/proc/openprom/banner-name", os.R_OK):
1123  system = open("/proc/openprom/banner-name", "r").read()
1124  hwdict['platform'] = uname
1125  hwdict['count'] = get_entry(tmpdict, 'ncpus probed')
1126  hwdict['model'] = get_entry(tmpdict, 'cpu')
1127  hwdict['type'] = get_entry(tmpdict, 'type')
1128  hwdict['model_ver'] = get_entry(tmpdict, 'type')
1129  hwdict['bogomips'] = bogomips
1130  hwdict['vendor'] = 'sun'
1131  hwdict['cache'] = "" # pitty the kernel doesn't tell us this.
1132  speed = int(round(float(bogomips))) / 2
1133  hwdict['speed'] = speed
1134  hwdict['system'] = system
1135 
1136  else:
1137  # XXX: expand me. Be nice to others
1138  hwdict['platform'] = uname
1139  hwdict['count'] = 1 # Good as any
1140  hwdict['type'] = uname
1141  hwdict['model'] = uname
1142  hwdict['model_number'] = ""
1143  hwdict['model_ver'] = ""
1144  hwdict['model_rev'] = ""
1145  hwdict['cache'] = ""
1146  hwdict['bogomips'] = ""
1147  hwdict['other'] = ""
1148  hwdict['speed'] = 0
1149 
1150  # make sure we get the right number here
1151  if not hwdict["count"]:
1152  hwdict["count"] = 1
1153  else:
1154  try:
1155  hwdict["count"] = int(hwdict["count"])
1156  except:
1157  hwdict["count"] = 1
1158  else:
1159  if hwdict["count"] == 0: # we have at least one
1160  hwdict["count"] = 1
1161 
1162  # If the CPU can do frequency scaling the CPU speed returned
1163  # by /proc/cpuinfo might be less than the maximum possible for
1164  # the processor. Check sysfs for the proper file, and if it
1165  # exists, use that value. Only use the value from CPU #0 and
1166  # assume that the rest of the CPUs are the same.
1167 
1168  if os.path.exists('/sys/devices/system/cpu/cpu0/cpufreq/cpuinfo_max_freq'):
1169  hwdict['speed'] = int(file('/sys/devices/system/cpu/cpu0/cpufreq/cpuinfo_max_freq').read().strip()) / 1000
1170 
1171  # This whole things hurts a lot.
1172  return hwdict
1173 
1174 
1175 
1177  un = os.uname()
1178  kernel = un[2]
1179  if kernel[:2] == "5.":
1180  return read_memory_2_6()
1181  if kernel[:2] == "4.":
1182  return read_memory_2_6()
1183  if kernel[:2] == "3.":
1184  return read_memory_2_6()
1185  if kernel[:3] == "2.6":
1186  return read_memory_2_6()
1187  if kernel[:3] == "2.4":
1188  return read_memory_2_4()
1189 
1191  if not os.access("/proc/meminfo", os.R_OK):
1192  return {}
1193 
1194  meminfo = open("/proc/meminfo", "r").read()
1195  lines = meminfo.split("\n")
1196  curline = lines[1]
1197  memlist = curline.split()
1198  memdict = {}
1199  memdict['class'] = "MEMORY"
1200  megs = int(long(memlist[1])/(1024*1024))
1201  if megs < 32:
1202  megs = megs + (4 - (megs % 4))
1203  else:
1204  megs = megs + (16 - (megs % 16))
1205  memdict['ram'] = str(megs)
1206  curline = lines[2]
1207  memlist = curline.split()
1208  # otherwise, it breaks on > ~4gigs of swap
1209  megs = int(long(memlist[1])/(1024*1024))
1210  memdict['swap'] = str(megs)
1211  return memdict
1212 
1214  if not os.access("/proc/meminfo", os.R_OK):
1215  return {}
1216  meminfo = open("/proc/meminfo", "r").read()
1217  lines = meminfo.split("\n")
1218  dict = {}
1219  for line in lines:
1220  blobs = line.split(":", 1)
1221  key = blobs[0]
1222  if len(blobs) == 1:
1223  continue
1224  #print blobs
1225  value = blobs[1].strip()
1226  dict[key] = value
1227 
1228  memdict = {}
1229  memdict["class"] = "MEMORY"
1230 
1231  total_str = dict['MemTotal']
1232  blips = total_str.split(" ")
1233  total_k = long(blips[0])
1234  megs = long(total_k/(1024))
1235 
1236  swap_str = dict['SwapTotal']
1237  blips = swap_str.split(' ')
1238  swap_k = long(blips[0])
1239  swap_megs = long(swap_k/(1024))
1240 
1241  memdict['ram'] = str(megs)
1242  memdict['swap'] = str(swap_megs)
1243  return memdict
1244 
1245 
1246 def create_profile_nocatch(gate, uuid):
1247  return _HardwareProfile(gate, uuid)
1248 
1249 
1250 
1253 def create_profile(gate, uuid):
1254  try:
1255  return create_profile_nocatch(gate, uuid)
1256  except SystemBusError, e:
1257  error(_('Error:') + ' ' + e.msg)
1258  if e.hint is not None:
1259  error('\t' + _('Hint:') + ' ' + e.hint)
1260  sys.exit(8)
1261 
1262 
1263 def get_profile_link(smoonURL, pub_uuid):
1264  return urljoin(smoonURL, '/client/show/%s' % pub_uuid)
1265 
1267  try:
1268  UUID = file(hw_uuid_file).read().strip()
1269  except IOError:
1270  try:
1271  UUID = file('/proc/sys/kernel/random/uuid').read().strip()
1272  try:
1273  file(hw_uuid_file, 'w').write(UUID)
1274  except Exception, e:
1275  raise UUIDError, 'Unable to save UUID to %s. Please run once as root.' % hw_uuid_file
1276  except IOError:
1277  sys.stderr.write(_('Unable to determine UUID of system!\n'))
1278  raise UUIDError, 'Could not determine UUID of system!\n'
1279  return UUID
1280 
1281 def read_pub_uuid(uuiddb, uuid, user_agent=user_agent, smoonURL=smoonURL, timeout=timeout, silent=False):
1282  smoonURLparsed=urlparse(smoonURL)
1283  res = uuiddb.get_pub_uuid(uuid, smoonURLparsed[1])
1284  if res:
1285  return res
1286 
1287  grabber = urlgrabber.grabber.URLGrabber(user_agent=user_agent, timeout=timeout, proxies=proxies)
1288  try:
1289  o = grabber.urlopen(urljoin(smoonURL + "/", '/client/pub_uuid/%s' % uuid))
1290  pudict = json.loads(o.read())
1291  o.close()
1292  uuiddb.set_pub_uuid(uuid, smoonURLparsed[1], pudict["pub_uuid"])
1293  return pudict["pub_uuid"]
1294  except Exception, e:
1295  if not silent:
1296  error(_('Error determining public UUID: %s') % e)
1297  sys.stderr.write(_("Unable to determine Public UUID! This could be a network error or you've\n"))
1298  sys.stderr.write(_("not submitted your profile yet.\n"))
1299  raise PubUUIDError, 'Could not determine Public UUID!\n'
def write(text, progress=True)
Definition: mythburn.py:279
def reset_resolver()
Definition: smolt.py:396
def serverMessage(page)
Definition: smolt.py:379
def create_profile_nocatch(gate, uuid)
Definition: smolt.py:1246
def get_distro_specific_data(self, gate)
Definition: smolt.py:519
#define round(x)
Definition: mythplayer.cpp:66
def get_file_systems(gate)
Definition: smolt.py:332
def __init__(self, gate, uuid)
Definition: smolt.py:204
def write_pub_uuid(self, uuiddb, smoonURL, pub_uuid, uuid)
Definition: smolt.py:612
def __init__(self, message, hint=None)
Definition: smolt.py:414
def write_admin_token(self, smoonURL, admin, admin_token_file)
Definition: smolt.py:623
def read(device=None, features=[])
Definition: disc.py:35
def get_submission_data(self, prefered_protocol=None)
Definition: smolt.py:632
def read_pub_uuid(uuiddb, uuid, user_agent=user_agent, smoonURL=smoonURL, timeout=timeout, silent=False)
Definition: smolt.py:1281
def to_ascii(o, current_encoding='utf-8')
Definition: smolt.py:192
def ignoreDevice(device)
Definition: smolt.py:353
def __init__(self, message)
Definition: smolt.py:422
def create_profile(gate, uuid)
For refactoring, I'll probably want to make a library Of command line tool functions This is one of t...
Definition: smolt.py:1253
def send(self, uuiddb, uuid, user_agent=user_agent, smoonURL=smoonURL, timeout=timeout, proxies=proxies, batch=False)
Definition: smolt.py:654
def get_sendable_fss(self, protocol_version=smoltProtocol)
Definition: smolt.py:609
def regenerate_pub_uuid(self, uuiddb, uuid, user_agent=user_agent, smoonURL=smoonURL, timeout=timeout)
Definition: smolt.py:775
def __init__(self, gate, uuid)
Definition: smolt.py:437
def get_sendable_devices(self, protocol_version=smoltProtocol)
Definition: smolt.py:557
def __init__(self, value)
Definition: smolt.py:374
def error(message)
Definition: smolt.py:389
def get_config_attr(attr, default="")
Definition: smolt_config.py:22
def debug(message)
Definition: smolt.py:392
def __init__(self, message)
Definition: smolt.py:429
def get_profile_link(smoonURL, pub_uuid)
This is another.
Definition: smolt.py:1263
def get_sendable_host(self, protocol_version=smoltProtocol)
Definition: smolt.py:584