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