00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023 import sys
00024 import time
00025 import os
00026 import getpass
00027
00028
00029 def ensure_code_reachability():
00030 _code_location = '/usr/share/smolt/client'
00031 if sys.path[-1] == _code_location:
00032 return
00033 sys.path.append(_code_location)
00034
00035
00036 def command_line():
00037 ensure_code_reachability()
00038 from i18n import _
00039 import smolt
00040
00041 from optparse import OptionParser
00042 parser = OptionParser(version = smolt.clientVersion)
00043
00044 parser.add_option('-d', '--debug',
00045 dest = 'DEBUG',
00046 default = False,
00047 action = 'store_true',
00048 help = _('enable debug information'))
00049 parser.add_option('--config',
00050 dest = 'the_only_config_file',
00051 default = None,
00052 metavar = 'file.cfg',
00053 help = _('specify the location of the (only) config file to use'))
00054 parser.add_option('-s', '--server',
00055 dest = 'smoonURL',
00056 default = smolt.smoonURL,
00057 metavar = 'smoonURL',
00058 help = _('specify the URL of the server (default "%default")'))
00059 parser.add_option('--username',
00060 dest = 'userName',
00061 default = None,
00062 metavar = 'userName',
00063 help = _('(optional) Fedora Account System registration'))
00064 parser.add_option('--password',
00065 dest = 'password',
00066 default = None,
00067 metavar = 'password',
00068 help = _('password, will prompt if not specified'))
00069 parser.add_option('-p', '--printOnly',
00070 dest = 'printOnly',
00071 default = False,
00072 action = 'store_true',
00073 help = _('print information only, do not send'))
00074 parser.add_option('-a', '--autoSend',
00075 dest = 'autoSend',
00076 default = False,
00077 action = 'store_true',
00078 help = _('don\'t prompt to send, just send'))
00079 parser.add_option('-r', '--retry',
00080 dest = 'retry',
00081 default = False,
00082 action = 'store_true',
00083 help = _('continue to send until success'))
00084 parser.add_option('-u', '--useragent', '--user_agent',
00085 dest = 'user_agent',
00086 default = smolt.user_agent,
00087 metavar = 'USERAGENT',
00088 help = _('specify HTTP user agent (default "%default")'))
00089 parser.add_option('-t', '--timeout',
00090 dest = 'timeout',
00091 type = 'float',
00092 default = smolt.timeout,
00093 help = _('specify HTTP timeout in seconds (default %default seconds)'))
00094 parser.add_option('-c', '--checkin',
00095 dest = 'cron_mode',
00096 default = False,
00097 action = 'store_true',
00098 help = _('do an automated checkin as when run from cron (implies --autoSend)'))
00099 parser.add_option('-S', '--scanOnly',
00100 dest = 'send_profile',
00101 default = True,
00102 action = 'store_false',
00103 help = _('only scan this machine for known hardware errata, do not send profile.'))
00104 parser.add_option('--submitOnly',
00105 dest = 'scan_remote',
00106 default = True,
00107 action = 'store_false',
00108 help = _('do not scan this machine for know hardware errata, only submit profile.'))
00109 parser.add_option('--uuidFile',
00110 dest = 'uuidFile',
00111 default = smolt.hw_uuid_file,
00112 help = _('specify which uuid to use, useful for debugging and testing mostly.'))
00113
00114
00115
00116
00117
00118 parser.add_option('-n', '--newPublicUUID',
00119 dest = 'new_pub',
00120 default = False,
00121 action = 'store_true',
00122 help = _('Request a new public UUID'))
00123 parser.add_option('--http-proxy',
00124 dest = 'httpproxy',
00125 default = None,
00126 help = _('HTTP proxy'))
00127
00128 (opts, args) = parser.parse_args()
00129
00130 if opts.cron_mode:
00131
00132 opts.autoSend = True
00133
00134 return opts, args
00135
00136
00137 def make_display_excerpts(profile):
00138 ensure_code_reachability()
00139 from i18n import _
00140 from smolt import to_ascii
00141
00142 def inner_indent(text):
00143 return ('\n' + 5 * ' ').join(text.split('\n'))
00144
00145 excerpts = {
00146 'label_intro':_('Smolt has collected four types of information:'),
00147 'label_question':_('Do you want to ..'),
00148 'label_question_view':_('(v)iew details on collected information?'),
00149 'label_question_send':_('(s)end this information to the Smolt server?'),
00150 'label_question_quit':_('(q)uit Smolt?'),
00151 'label_general':_('General'),
00152 'label_devices':_('Devices'),
00153 'label_fs_related':_('File system-related'),
00154 'label_distro_specific':_('Distribution-specific'),
00155
00156 'general':inner_indent(to_ascii(profile.get_general_info_excerpt())),
00157 'devices':inner_indent(to_ascii(profile.get_devices_info_excerpt())),
00158 'file_system':inner_indent(to_ascii(profile.get_file_system_info_excerpt())),
00159 'distro':inner_indent(to_ascii(profile.get_distro_info_excerpt())),
00160 }
00161 return excerpts
00162
00163
00164 def dump_excerpts(excerpts):
00165 print """\
00166 =====================================================
00167 %(label_intro)s
00168
00169 %(label_general)s
00170 %(general)s
00171
00172 %(label_devices)s
00173 %(devices)s
00174
00175 %(label_fs_related)s
00176 %(file_system)s
00177
00178 %(label_distro_specific)s
00179 %(distro)s
00180
00181 =====================================================
00182 %(label_question)s
00183 %(label_question_view)s
00184 %(label_question_send)s
00185 %(label_question_quit)s
00186 """ % excerpts
00187
00188
00189 def present_and_require_confirmation(profile):
00190 import subprocess
00191 from tempfile import NamedTemporaryFile
00192
00193 ensure_code_reachability()
00194 from i18n import _
00195 from smolt import error
00196
00197 excerpts = make_display_excerpts(profile)
00198
00199 submit = False
00200 while not submit:
00201 dump_excerpts(excerpts)
00202
00203 try:
00204 choice = raw_input(_('Your choice (s)end (v)iew (q)uit: ')).strip()
00205 except KeyboardInterrupt:
00206 error(_('Exiting...'))
00207 sys.exit(4)
00208 if choice in (_('s|y|yes')).split('|'):
00209 submit = True
00210 print '\n\n'
00211 elif choice in (_('q|n|no')).split('|'):
00212 sys.exit(0)
00213 elif choice in (_('v')).split('|'):
00214 f = NamedTemporaryFile()
00215 for line in profile.getProfile():
00216 try:
00217 f.write(line + '\n')
00218 except UnicodeEncodeError:
00219 pass
00220 f.flush()
00221 os.chmod(f.name, 0400)
00222 try:
00223 pager_command = os.environ['PAGER']
00224 except KeyError:
00225 if os.path.exists('/usr/bin/less'):
00226 pager_command = '/usr/bin/less'
00227 elif os.path.exists('/bin/less'):
00228 pager_command = '/bin/less'
00229 else:
00230
00231 pager_command = 'more'
00232 try:
00233 subprocess.call([pager_command, f.name])
00234 except NameError:
00235 os.system(' '.join([pager_command, f.name]))
00236 f.close()
00237 print '\n\n'
00238 else:
00239 error(_('Exiting...'))
00240 sys.exit(4)
00241
00242
00243 def do_send_profile(uuiddb, uuid, profile, opts, proxies):
00244 (error_code, pub_uuid, admin) = profile.send(uuiddb, uuid, user_agent=opts.user_agent,
00245 smoonURL=opts.smoonURL,
00246 timeout=opts.timeout,
00247 proxies=proxies,
00248 batch=opts.cron_mode)
00249 return (error_code, pub_uuid, admin)
00250
00251
00252 def send_profile(uuiddb, uuid, profile, opts, proxies):
00253 ensure_code_reachability()
00254 from i18n import _
00255 from smolt import error
00256
00257 if opts.retry:
00258 while 1:
00259 (error_code, pub_uuid, admin) = do_send_profile(uuiddb, uuid, profile, opts, proxies)
00260 if not error_code:
00261 break
00262 error(_('Retry Enabled - Retrying'))
00263 time.sleep(30)
00264 else:
00265 (error_code, pub_uuid, admin) = do_send_profile(uuiddb, uuid, profile, opts, proxies)
00266 if error_code:
00267 print _('Could not send - Exiting')
00268 sys.exit(1)
00269
00270 return (error_code, pub_uuid, admin)
00271
00272
00273 def mention_profile_web_view(opts, pub_uuid, admin):
00274 ensure_code_reachability()
00275 import smolt
00276 from i18n import _
00277
00278 pubUrl = smolt.get_profile_link(opts.smoonURL, pub_uuid)
00279 print
00280 print _('To share your profile: \n\t%s (public)') % pubUrl
00281 if not smolt.secure:
00282 print _('\tAdmin Password: %s') % admin
00283
00284
00285 def get_proxies(opts):
00286 if opts.httpproxy == None:
00287 proxies = None
00288 else:
00289 proxies = {'http':opts.httpproxy}
00290 return proxies
00291
00292
00293 def read_profile(gate, uuid):
00294 ensure_code_reachability()
00295 from i18n import _
00296 import smolt
00297
00298 try:
00299 profile = smolt.create_profile(gate, uuid)
00300 except smolt.UUIDError, e:
00301 sys.stderr.write(_('%s\n' % e))
00302 sys.exit(9)
00303 return profile
00304
00305
00306 def register_with_fedora_account_system(opts):
00307 ensure_code_reachability()
00308 from i18n import _
00309
00310 if not opts.password:
00311 password = getpass.getpass('\n' + _('Password:') + ' ')
00312 else:
00313 password = opts.password
00314
00315 if profile.register(userName=opts.userName, password=password, user_agent=opts.user_agent, smoonURL=opts.smoonURL, timeout=opts.timeout):
00316 print _('Registration Failed, Try again')
00317
00318
00319 def do_scan_remote(profile, opts, gate):
00320 ensure_code_reachability()
00321 from scan import scan, rating
00322
00323 scan(profile, opts.smoonURL, gate)
00324 try:
00325 rating(profile, opts.smoonURL, gate)
00326 except ValueError:
00327 print "Could not get rating!"
00328
00329
00330 def mention_missing_uuid():
00331 ensure_code_reachability()
00332 from i18n import _
00333 print
00334 print _('No Public UUID found! Please re-run with -n to generate a new public uuid')
00335
00336
00337 def main_request_new_public_uuid(uuiddb, uuid, profile, opts):
00338 ensure_code_reachability()
00339 from i18n import _
00340 from smolt import error, ServerError
00341
00342 try:
00343 pub_uuid = profile.regenerate_pub_uuid(uuiddb, uuid, user_agent=opts.user_agent,
00344 smoonURL=opts.smoonURL,
00345 timeout=opts.timeout)
00346 except ServerError, e:
00347 error(_('Error contacting server: %s') % str(e))
00348 sys.exit(1)
00349
00350 print _('Success! Your new public UUID is: %s' % pub_uuid)
00351 sys.exit(0)
00352
00353
00354 def main_scan_only(profile, opts, gate):
00355 do_scan_remote(profile, opts, gate)
00356 sys.exit(0)
00357
00358
00359 def main_print_only(profile):
00360 for line in profile.getProfile():
00361 if not line.startswith('#'):
00362 print line.encode('utf-8')
00363 sys.exit(0)
00364
00365
00366 def main_send_profile(uuiddb, uuid, profile, opts, gate):
00367 proxies = get_proxies(opts)
00368
00369 if not opts.autoSend:
00370 present_and_require_confirmation(profile)
00371
00372 (error_code, pub_uuid, admin) = send_profile(uuiddb, uuid, profile, opts, proxies)
00373
00374 if opts.userName:
00375 register_with_fedora_account_system(opts)
00376
00377 if opts.scan_remote and not opts.cron_mode:
00378 do_scan_remote(profile, opts, gate)
00379
00380 if pub_uuid:
00381 mention_profile_web_view(opts, pub_uuid, admin)
00382 elif not opts.cron_mode:
00383 mention_missing_uuid()
00384
00385
00386 def main():
00387 ensure_code_reachability()
00388 from i18n import _
00389 import smolt
00390 from gate import create_default_gate, create_gate_from_file
00391 from uuiddb import create_default_uuiddb
00392
00393 (opts, args) = command_line()
00394
00395 if opts.the_only_config_file is None:
00396 gate = create_default_gate()
00397 else:
00398 gate = create_gate_from_file(opts.the_only_config_file)
00399
00400 smolt.DEBUG = opts.DEBUG
00401 smolt.hw_uuid_file = opts.uuidFile
00402
00403 profile = read_profile(gate, smolt.read_uuid())
00404
00405 if opts.new_pub:
00406 uuiddb = create_default_uuiddb()
00407 uuid = smolt.read_uuid()
00408 main_request_new_public_uuid(uuiddb, uuid, profile, opts)
00409 elif not opts.send_profile:
00410 main_scan_only(profile, opts)
00411 elif opts.printOnly and not opts.autoSend:
00412 main_print_only(profile)
00413 else:
00414 uuiddb = create_default_uuiddb()
00415 uuid = smolt.read_uuid()
00416 main_send_profile(uuiddb, uuid, profile, opts, gate)
00417
00418
00419 if __name__ == '__main__':
00420 main()