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