00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019 import ConfigParser
00020 import logging
00021 import os , sys
00022 sys.path.extend(map(os.path.abspath, ['../../']))
00023 from smolt_config import get_config_attr
00024 from request import Request
00025
00026 _SECTION = 'MAIN'
00027
00028
00029 def _get_option_name(hw_uuid, host):
00030 return '%s__%s' % (hw_uuid, host)
00031
00032 class UUIDError(Exception):
00033 def __init__(self, message):
00034 self.msg = message
00035
00036 def __str__(self):
00037 return str(self.msg)
00038
00039 class PubUUIDError(Exception):
00040 def __init__(self, message):
00041 self.msg = message
00042
00043 def __str__(self):
00044 return str(self.msg)
00045
00046 class _UuidDb:
00047 hw_uuid = None
00048
00049 def __init__(self, database_filename):
00050 self._database_filename = database_filename
00051 self._config = ConfigParser.RawConfigParser()
00052 self._config.read(self._database_filename)
00053 if not self._config.has_section(_SECTION):
00054 self._config.add_section(_SECTION)
00055 self.hw_uuid_file = get_config_attr('HW_UUID', '/etc/smolt/hw-uuid')
00056
00057 def _flush(self):
00058 try:
00059 smolt_user_config_dir = os.path.expanduser('~/.smolt/')
00060 if not os.path.exists(smolt_user_config_dir):
00061 os.mkdir(smolt_user_config_dir, 0700)
00062 f = open(self._database_filename, 'w')
00063 self._config.write(f)
00064 f.close()
00065 except:
00066 logging.error('Flushing UUID database failed')
00067
00068 def get_pub_uuid(self, hw_uuid, host):
00069 try:
00070 pub_uuid = self._config.get(_SECTION, _get_option_name(hw_uuid, host))
00071 logging.info('Public UUID "%s" read from database' % pub_uuid)
00072 return pub_uuid
00073 except ConfigParser.NoOptionError:
00074 try:
00075 req = Request('/client/pub_uuid/%s' % self.get_priv_uuid())
00076 pudict = json.loads(req.open().read())
00077 self.set_pub_uuid(self.hw_uuid, Request(), pudict['pub_uuid'])
00078 return pudict['pub_uuid']
00079 except Exception, e:
00080 error(_('Error determining public UUID: %s') % e)
00081 sys.stderr.write(_("Unable to determine Public UUID! This could be a network error or you've\n"))
00082 sys.stderr.write(_("not submitted your profile yet.\n"))
00083 raise PubUUIDError, 'Could not determine Public UUID!\n'
00084
00085 def set_pub_uuid(self, hw_uuid, host, pub_uuid):
00086 for i in (hw_uuid, host, pub_uuid):
00087 if not i:
00088 raise Exception('No paramater allowed to be None.')
00089 self._config.set(_SECTION, _get_option_name(hw_uuid, host), pub_uuid)
00090 logging.info('Public UUID "%s" written to database' % pub_uuid)
00091 self._flush()
00092
00093 def gen_uuid(self):
00094 try:
00095 return file('/proc/sys/kernel/random/uuid').read().strip()
00096 except IOError:
00097 try:
00098 import uuid
00099 return uuid.uuid4()
00100 except:
00101 raise UUIDError('Could not generate new UUID!')
00102
00103 def get_priv_uuid(self):
00104 if self.hw_uuid:
00105 return self.hw_uuid
00106
00107 try:
00108 self.hw_uuid = file(self.hw_uuid_file).read().strip()
00109 except IOError:
00110 try:
00111 self.hw_uuid = self.genUUID()
00112 except UUIDError:
00113 raise UUIDError('Unable to determine UUID of system!')
00114 try:
00115
00116 file(self.hw_uuid_file).write(self.hw_uuid)
00117 except Exception, e:
00118 raise UUIDError('Unable to save UUID to %s. Please run once as root.' % self.hw_uuid_file)
00119
00120 return self.hw_uuid
00121
00122 _uuid_db_instance = None
00123 def UuidDb():
00124 """Simple singleton wrapper with lazy initialization"""
00125 global _uuid_db_instance
00126 if _uuid_db_instance == None:
00127 import config
00128 from smolt import get_config_attr
00129 _uuid_db_instance = _UuidDb(get_config_attr("UUID_DB", os.path.expanduser('~/.smolt/uuiddb.cfg')))
00130 return _uuid_db_instance