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