def check_requires(_): """ Check prerequisites and report if any are missing. """ missing_repos = [] main_repo_missing = False repos = repository.repositoriesFromDefinition('local', '') for r in repos: missing_repos += r.check_requires(installed_repos) if len(missing_repos) == 0: return SKIP_SCREEN text2 = '' for r in missing_repos: if r.startswith(constants.MAIN_REPOSITORY_NAME): main_repo_missing = True text2 += " * %s\n" % r if main_repo_missing: text = "This Supplemental Pack is not compatible with this version of %s." % (version.PRODUCT_BRAND or version.PLATFORM_NAME) else: text = "The following dependencies have not yet been installed:\n\n" + text2 + \ "\nPlease install them first and try again." ButtonChoiceWindow( tui.screen, "Error", text, ['Back']) return LEFT_BACKWARDS
def verify_source(answers, label, require_base_repo): cap_label = ' '.join(map(lambda a: a.capitalize(), label.split())) if 'source-media' in answers and 'source-address' in answers: media = answers['source-media'] address = answers['source-address'] else: media = 'local' address = '' done = False SKIP, VERIFY = range(2) entries = [ ("Skip verification", SKIP), ("Verify %s source" % label, VERIFY), ] if media == 'local': text = "Would you like to test your media?" default = selectDefault(VERIFY, entries) else: text = "Would you like to test your %s repository? This may cause significant network traffic." % label default = selectDefault(SKIP, entries) while not done: (button, entry) = ListboxChoiceWindow(tui.screen, "Verify %s Source" % cap_label, text, entries, ['Ok', 'Back'], default=default, help='vfyrepo') if button == 'back': return LEFT_BACKWARDS if entry == VERIFY: # we need to do the verification: try: tui.progress.showMessageDialog("Please wait", "Searching for repository...") repos = repository.repositoriesFromDefinition(media, address) tui.progress.clearModelessDialog() if require_base_repo and constants.MAIN_REPOSITORY_NAME not in [ r.identifier() for r in repos ]: ButtonChoiceWindow( tui.screen, "Error", """A base installation repository was not found. Please check the address was valid and/or that the media was inserted correctly, and try again.""", ['Ok']) else: done = interactive_source_verification(repos, label) except Exception as e: xelogging.logException(e) ButtonChoiceWindow( tui.screen, "Error", """Unable to access location specified. Please check the address was valid and/or that the media was inserted correctly, and try again.""", ['Ok']) else: done = True return RIGHT_FORWARDS
def check_repo_def(definition, require_base_repo): """ Check that the repository source definition gives access to suitable repositories. """ try: tui.progress.showMessageDialog("Please wait", "Searching for repository...") repos = repository.repositoriesFromDefinition(*definition) tui.progress.clearModelessDialog() except Exception, e: xelogging.log("Exception trying to access repository: %s" % e) tui.progress.clearModelessDialog() return REPOCHK_NO_ACCESS
def verify_source(answers, label, require_base_repo): cap_label = ' '.join(map(lambda a: a.capitalize(), label.split())) if 'source-media' in answers and 'source-address' in answers: media = answers['source-media'] address = answers['source-address'] else: media = 'local' address = '' done = False SKIP, VERIFY = range(2) entries = [ ("Skip verification", SKIP), ("Verify %s source" % label, VERIFY), ] if media == 'local': text = "Would you like to test your media?" default = selectDefault(VERIFY, entries) else: text = "Would you like to test your %s repository? This may cause significant network traffic." % label default = selectDefault(SKIP, entries) while not done: (button, entry) = ListboxChoiceWindow( tui.screen, "Verify %s Source" % cap_label, text, entries, ['Ok', 'Back'], default = default, help = 'vfyrepo') if button == 'back': return LEFT_BACKWARDS if entry == VERIFY: # we need to do the verification: try: tui.progress.showMessageDialog("Please wait", "Searching for repository...") repos = repository.repositoriesFromDefinition(media, address) tui.progress.clearModelessDialog() if require_base_repo and constants.MAIN_REPOSITORY_NAME not in [r.identifier() for r in repos]: ButtonChoiceWindow( tui.screen, "Error", """A base installation repository was not found. Please check the address was valid and/or that the media was inserted correctly, and try again.""", ['Ok']) else: done = interactive_source_verification(repos, label) except: ButtonChoiceWindow( tui.screen, "Error", """Unable to access location specified. Please check the address was valid and/or that the media was inserted correctly, and try again.""", ['Ok']) else: done = True return RIGHT_FORWARDS
def check_repo_def(definition, require_base_repo): """ Check that the repository source definition gives access to suitable repositories. """ try: tui.progress.showMessageDialog("Please wait", "Searching for repository...") repos = repository.repositoriesFromDefinition(*definition) tui.progress.clearModelessDialog() except Exception as e: logger.log("Exception trying to access repository: %s" % e) logger.logException(e) tui.progress.clearModelessDialog() return REPOCHK_NO_ACCESS else: if len(repos) == 0: return REPOCHK_NO_REPO elif constants.MAIN_REPOSITORY_NAME not in [r.identifier() for r in repos] and require_base_repo: return REPOCHK_NO_BASE_REPO return REPOCHK_NO_ERRORS
def get_more_media(_): """ 'Please insert disk' dialog. """ done = False while not done: text = '' for need in still_need: if text == '': text = "The following Supplemental Packs must be supplied to complete installation:\n\n" text += " * %s\n" % need text += "\nWhen there are no more Supplemental Packs to install press Skip." more = ButtonChoiceWindow(tui.screen, "New Media", "Please insert your Supplemental Pack now.\n" + text, ['Ok', 'Skip'], 40) if more == "skip": # they hit cancel: confirm = "skip" if len(still_need) > 0: # check they mean it check_text = "The following Supplemental Packs could contain packages which are essential:\n\n" for need in still_need: check_text += " * %s\n" % need check_text += "\nAre you sure you wish to skip installing them?" confirm = ButtonChoiceWindow(tui.screen, "Essential Packages", check_text, ['Back', 'Skip']) if confirm == "skip": rv = EXIT done = True else: # they hit OK - check there is a disc repos = repository.repositoriesFromDefinition('local', '') if len(repos) == 0: ButtonChoiceWindow( tui.screen, "Error", "No installation files were found - please check your disc and try again.", ['Back']) else: # found repositories - can leave this screen rv = RIGHT_FORWARDS done = True return rv
def go(ui, args, answerfile_address, answerfile_script): extra_repo_defs = [] results = { 'keymap': None, 'serial-console': None, 'operation': init_constants.OPERATION_INSTALL, 'boot-serial': False, 'extra-repos': [], 'network-backend': constants.NETWORK_BACKEND_DEFAULT, 'root-password': ('pwdhash', '!!'), 'create-new-partitions': True, # FALSE = DOS | TRUE = GPT set via command line only with --disable-gpt 'new-partition-layout': False, # TRUE = GPT with LOG,BACKUP,ROOT,BOOT,SWAP,SR automatically set during install/upgrade 'services': {s: None for s in constants.SERVICES }, # default state for services, example {'sshd': None} } suppress_extra_cd_dialog = False serial_console = None boot_console = None boot_serial = False if not xen_control_domain() or '--virtual' in args: hardware.useVMHardwareFunctions() for (opt, val) in args.items(): if opt == "--boot-console": # takes precedence over --console if hardware.is_serialConsole(val): boot_console = hardware.getSerialConfig() elif opt == "--console": for console in val: if hardware.is_serialConsole(console): serial_console = hardware.getSerialConfig() if hardware.is_serialConsole(val[-1]): boot_serial = True elif opt == "--keymap": results["keymap"] = val logger.log("Keymap specified on command-line: %s" % val) elif opt == "--extrarepo": extra_repo_defs += val elif opt == "--onecd": suppress_extra_cd_dialog = True elif opt == "--disable-gpt": constants.GPT_SUPPORT = False results["create-new-partitions"] = False logger.log( "Forcing DOS partition table and old partition layout via command-line" ) elif opt == "--legacy-partitions": results["create-new-partitions"] = False logger.log("Forcing old partition layout via command-line") elif opt == "--cc-preparations": constants.CC_PREPARATIONS = True results['network-backend'] = constants.NETWORK_BACKEND_BRIDGE if boot_console and not serial_console: serial_console = boot_console boot_serial = True if serial_console: try: results['serial-console'] = hardware.SerialPort.from_string( serial_console) results['boot-serial'] = boot_serial logger.log( "Serial console specified on command-line: %s, default boot: %s" % (serial_console, boot_serial)) except: pass interactive = True try: if os.path.isfile(constants.defaults_data_file): data_file = open(constants.defaults_data_file) try: defaults = json.load(data_file) finally: data_file.close() results.update(defaults) # loading an answerfile? assert ui is not None or answerfile_address is not None or answerfile_script is not None if answerfile_address and answerfile_script: raise RuntimeError( "Both answerfile and answerfile generator passed on command line." ) a = None parsing_except = None if answerfile_address: a = answerfile.Answerfile.fetch(answerfile_address) elif answerfile_script: a = answerfile.Answerfile.generate(answerfile_script) if a: interactive = False results['network-hardware'] = netutil.scanConfiguration() try: results.update(a.parseScripts()) results.update(a.processAnswerfileSetup()) if ui and results.get('ui-confirmation-prompt', False): if not ui.init.confirm_proceed(): logger.log("User did not confirm installation. Reboot") return constants.EXIT_USER_CANCEL if 'extra-repos' in results: # load drivers now for media, address in results['extra-repos']: for r in repository.repositoriesFromDefinition( media, address, drivers=True): r.installPackages(lambda x: (), {'root': '/'}) if 'fcoe-interfaces' in results: fcoeutil.start_fcoe(results['fcoe-interfaces']) util.runCmd2(util.udevsettleCmd()) time.sleep(1) diskutil.mpath_part_scan() # ensure partitions/disks are not locked by LVM lvm = disktools.LVMTool() lvm.deactivateAll() del lvm diskutil.log_available_disks() results.update(a.processAnswerfile()) results = fixMpathResults(results) except Exception as e: logger.logException(e) parsing_except = e results['extra-repos'] += extra_repo_defs logger.log("Driver repos: %s" % str(results['extra-repos'])) scripts.run_scripts('installation-start') if parsing_except: raise parsing_except # log the modules that we loaded: logger.log("All needed modules should now be loaded. We have loaded:") util.runCmd2(["lsmod"]) status = constants.EXIT_OK # how much RAM do we have? ram_found_mb = hardware.getHostTotalMemoryKB() / 1024 ram_warning = ram_found_mb < constants.MIN_SYSTEM_RAM_MB vt_warning = not hardware.VTSupportEnabled() # Generate the UI sequence and populate some default # values in backend input. Note that not all these screens # will be displayed as they have conditional to skip them at # the start of each function. In future these conditionals will # be moved into the sequence definition and evaluated by the # UI dispatcher. aborted = False if ui and interactive: uiexit = ui.installer.runMainSequence(results, ram_warning, vt_warning, suppress_extra_cd_dialog) if uiexit == uicontroller.EXIT: aborted = True if not aborted: if results['install-type'] == constants.INSTALL_TYPE_RESTORE: logger.log('INPUT ANSWER DICTIONARY') backend.prettyLogAnswers(results) logger.log("SCRIPTS DICTIONARY:") backend.prettyLogAnswers(scripts.script_dict) logger.log("Starting actual restore") backup = results['backup-to-restore'] if ui: pd = tui.progress.initProgressDialog( "Restoring %s" % backup, "Restoring data - this may take a while...", 100) def progress(x): if ui and pd: tui.progress.displayProgressDialog(x, pd) restore.restoreFromBackup(backup, progress) if ui: tui.progress.clearModelessDialog() tui.progress.OKDialog( "Restore", "The restore operation completed successfully.") else: logger.log("Starting actual installation") backend.performInstallation(results, ui, interactive) if ui and interactive: ui.installer.screens.installation_complete() logger.log("The installation completed successfully.") else: logger.log( "The user aborted the installation from within the user interface." ) status = constants.EXIT_USER_CANCEL except Exception as e: try: # first thing to do is to get the traceback and log it: ex = sys.exc_info() err = str.join("", traceback.format_exception(*ex)) logger.log("INSTALL FAILED.") logger.log("A fatal exception occurred:") logger.log(err) # run the user's scripts - an arg of "1" indicates failure scripts.run_scripts('installation-complete', '1') # collect logs where possible xelogging.collectLogs("/tmp") # now display a friendly error dialog: if ui: ui.exn_error_dialog("install-log", True, interactive) else: txt = constants.error_string(str(e), 'install-log', True) logger.log(txt) # and now on the disk if possible: if 'primary-disk' in results and 'primary-partnum' in results and 'logs-partnum' in results: backend.writeLog(results['primary-disk'], results['primary-partnum'], results['logs-partnum']) elif 'primary-disk' in results and 'primary-partnum' in results: backend.writeLog(results['primary-disk'], results['primary-partnum'], None) logger.log(results) except Exception as e: # Don't let logging exceptions prevent subsequent actions print 'Logging failed: ' + str(e) # exit with failure status: status = constants.EXIT_ERROR else: # run the user's scripts - an arg of "0" indicates success try: scripts.run_scripts('installation-complete', '0') except: pass # put the log in /tmp: xelogging.collectLogs('/tmp') # and now on the disk if possible: if 'primary-disk' in results and 'primary-partnum' in results and 'logs-partnum' in results: backend.writeLog(results['primary-disk'], results['primary-partnum'], results['logs-partnum']) elif 'primary-disk' in results and 'primary-partnum' in results: backend.writeLog(results['primary-disk'], results['primary-partnum'], None) assert (status == constants.EXIT_OK or status == constants.EXIT_USER_CANCEL) return status
def confirm_load_repo(answers, label, installed_repos): cap_label = ' '.join(map(lambda a: a.capitalize(), label.split())) if 'source-media' in answers and 'source-address' in answers: media = answers['source-media'] address = answers['source-address'] else: media = 'local' address = '' try: tui.progress.showMessageDialog("Please wait", "Searching for repository...") repos = repository.repositoriesFromDefinition( media, address, drivers=(label == 'driver')) tui.progress.clearModelessDialog() except: ButtonChoiceWindow( tui.screen, "Error", """Unable to access location specified. Please check the address was valid and/or that the media was inserted correctly, and try again.""", ['Back']) return LEFT_BACKWARDS if label != 'driver': repos = filter( lambda r: r.identifier() != constants.MAIN_REPOSITORY_NAME, repos) if len(repos) == 0: ButtonChoiceWindow( tui.screen, "No %s Found" % cap_label, """No %s compatible %ss were found at the location specified. Please check the address was valid and/or that the media was inserted correctly, and try again.""" % (version.PRODUCT_BRAND or version.PLATFORM_NAME, label), ['Back']) return LEFT_BACKWARDS USE, VERIFY, BACK = range(3) default_button = BACK if len(repos) == 1: text = TextboxReflowed(54, "The following %s was found:\n\n" % label) else: text = TextboxReflowed(54, "The following %ss were found:\n\n" % label) buttons = ButtonBar(tui.screen, [('Use', 'use'), ('Verify', 'verify'), ('Back', 'back')]) cbt = CheckboxTree(4, scroll=1) for r in repos: if str(r) in installed_repos: cbt.append("%s (already installed)" % r.name(), r, False) else: cbt.append(r.name(), r, True) default_button = VERIFY gf = GridFormHelp(tui.screen, 'Load Repository', 'loadrepo', 1, 3) gf.add(text, 0, 0, padding=(0, 0, 0, 1)) gf.add(cbt, 0, 1, padding=(0, 0, 0, 1)) gf.add(buttons, 0, 2, growx=1) gf.draw() done = False while not done: gf.setCurrent(buttons.list[default_button][0]) rc = buttons.buttonPressed(gf.run()) selected_repos = cbt.getSelection() if rc in [None, 'use']: done = True elif rc == 'back': tui.screen.popWindow() return LEFT_BACKWARDS elif rc == 'verify' and len(selected_repos) > 0: if media == 'local': text2 = "\n\nWould you like to test your media?" else: text2 = "\n\nWould you like to test your %s repository? This may cause significant network traffic." % label rc2 = ButtonChoiceWindow(tui.screen, "Repository Information", text2, ['Ok', 'Back'], width=60) if rc2 == 'ok' and interactive_source_verification( selected_repos, label): default_button = USE tui.screen.popWindow() answers['repos'] = selected_repos return RIGHT_FORWARDS
def confirm_load_repo(answers, label, installed_repos): cap_label = ' '.join(map(lambda a: a.capitalize(), label.split())) if 'source-media' in answers and 'source-address' in answers: media = answers['source-media'] address = answers['source-address'] else: media = 'local' address = '' try: tui.progress.showMessageDialog("Please wait", "Searching for repository...") repos = repository.repositoriesFromDefinition(media, address) tui.progress.clearModelessDialog() except: ButtonChoiceWindow( tui.screen, "Error", """Unable to access location specified. Please check the address was valid and/or that the media was inserted correctly, and try again.""", ['Back']) return LEFT_BACKWARDS if label == 'driver': repos = filter(lambda r: True in map(lambda p: p.type.startswith('driver'), r), repos) else: repos = filter(lambda r: r.identifier() != constants.MAIN_REPOSITORY_NAME, repos) if len(repos) == 0: ButtonChoiceWindow( tui.screen, "No %s Found" % cap_label, """No %s compatible %ss were found at the location specified. Please check the address was valid and/or that the media was inserted correctly, and try again.""" % (version.PRODUCT_BRAND or version.PLATFORM_NAME, label), ['Back']) return LEFT_BACKWARDS USE, VERIFY, BACK = range(3) default_button = BACK if len(repos) == 1: text = TextboxReflowed(54, "The following %s was found:\n\n" % label) else: text = TextboxReflowed(54, "The following %ss were found:\n\n" % label) buttons = ButtonBar(tui.screen, [('Use', 'use'), ('Verify', 'verify'), ('Back', 'back')]) cbt = CheckboxTree(4, scroll = 1) for r in repos: if str(r) in installed_repos: cbt.append("%s (already installed)" % r.name(), r, False) else: cbt.append(r.name(), r, True) default_button = VERIFY gf = GridFormHelp(tui.screen, 'Load Repository', 'loadrepo', 1, 3) gf.add(text, 0, 0, padding = (0, 0, 0, 1)) gf.add(cbt, 0, 1, padding = (0, 0, 0, 1)) gf.add(buttons, 0, 2, growx = 1) gf.draw() done = False while not done: gf.setCurrent(buttons.list[default_button][0]) rc = buttons.buttonPressed(gf.run()) selected_repos = cbt.getSelection() if rc in [None, 'use']: done = True elif rc == 'back': tui.screen.popWindow() return LEFT_BACKWARDS elif rc == 'verify' and len(selected_repos) > 0: hashes = [" %s %s" % (r.md5sum(), r.name()) for r in selected_repos] text2 = "The following MD5 hashes have been calculated. Please check them against those provided by the supplier:\n\n" text2 += "\n".join(hashes) if media == 'local': text2 += "\n\nWould you like to test your media?" else: text2 += "\n\nWould you like to test your %s repository? This may cause significant network traffic." % label rc2 = ButtonChoiceWindow( tui.screen, "Repository Information", text2, ['Ok', 'Back'], width = 60) if rc2 == 'ok' and interactive_source_verification(selected_repos, label): default_button = USE tui.screen.popWindow() answers['repos'] = selected_repos return RIGHT_FORWARDS
def go(ui, args, answerfile_address, answerfile_script): extra_repo_defs = [] results = { 'keymap': None, 'serial-console': None, 'operation': init_constants.OPERATION_INSTALL, 'boot-serial': False, 'extra-repos': [], 'network-backend': constants.NETWORK_BACKEND_DEFAULT, 'root-password': ('pwdhash', '!!'), 'create-new-partitions': True, # FALSE = DOS | TRUE = GPT set via command line only with --disable-gpt 'new-partition-layout': False, # TRUE = GPT with LOG,BACKUP,ROOT,BOOT,SWAP,SR automatically set during install/upgrade } suppress_extra_cd_dialog = False serial_console = None boot_console = None boot_serial = False if not xen_control_domain() or args.has_key('--virtual'): hardware.useVMHardwareFunctions() for (opt, val) in args.items(): if opt == "--boot-console": # takes precedence over --console if hardware.is_serialConsole(val): boot_console = hardware.getSerialConfig() elif opt == "--console": for console in val: if hardware.is_serialConsole(console): serial_console = hardware.getSerialConfig() if hardware.is_serialConsole(val[-1]): boot_serial = True elif opt == "--keymap": results["keymap"] = val xelogging.log("Keymap specified on command-line: %s" % val) elif opt == "--extrarepo": extra_repo_defs += val elif opt == "--onecd": suppress_extra_cd_dialog = True elif opt == "--disable-gpt": constants.GPT_SUPPORT = False results["create-new-partitions"] = False xelogging.log("Forcing old partition layout via command-line") if boot_console and not serial_console: serial_console = boot_console boot_serial = True if serial_console: try: results['serial-console'] = hardware.SerialPort.from_string( serial_console) results['boot-serial'] = boot_serial xelogging.log( "Serial console specified on command-line: %s, default boot: %s" % (serial_console, boot_serial)) except: pass interactive = True try: if os.path.isfile(constants.defaults_data_file): data_file = open(constants.defaults_data_file) try: defaults = json.load(data_file) finally: data_file.close() results.update(defaults) # loading an answerfile? assert ui != None or answerfile_address != None or answerfile_script != None if answerfile_address and answerfile_script: raise RuntimeError, "Both answerfile and answerfile generator passed on command line." a = None parsing_except = None if answerfile_address: a = answerfile.Answerfile.fetch(answerfile_address) elif answerfile_script: a = answerfile.Answerfile.generate(answerfile_script) if a: interactive = False results['network-hardware'] = netutil.scanConfiguration() try: results.update(a.parseScripts()) results.update(a.processAnswerfileSetup()) if ui and results.get('ui-confirmation-prompt', False): if not ui.init.confirm_proceed(): xelogging.log( "User did not confirm installation. Reboot") return constants.EXIT_USER_CANCEL if results.has_key('extra-repos'): # load drivers now for media, address in results['extra-repos']: for r in repository.repositoriesFromDefinition( media, address, drivers=True): r.installPackages(lambda x: (), {'root': '/'}) if 'fcoe-interfaces' in results: fcoeutil.start_fcoe(results['fcoe-interfaces']) util.runCmd2(util.udevsettleCmd()) time.sleep(1) diskutil.mpath_part_scan() # ensure partitions/disks are not locked by LVM lvm = disktools.LVMTool() lvm.deactivateAll() del lvm diskutil.log_available_disks() results.update(a.processAnswerfile()) results = fixMpathResults(results) except Exception, e: xelogging.logException(e) parsing_except = e results['extra-repos'] += extra_repo_defs xelogging.log("Driver repos: %s" % str(results['extra-repos'])) scripts.run_scripts('installation-start') if parsing_except: raise parsing_except # log the modules that we loaded: xelogging.log( "All needed modules should now be loaded. We have loaded:") util.runCmd2(["lsmod"]) status = constants.EXIT_OK # how much RAM do we have? ram_found_mb = hardware.getHostTotalMemoryKB() / 1024 ram_warning = ram_found_mb < constants.MIN_SYSTEM_RAM_MB vt_warning = not hardware.VTSupportEnabled() # Generate the UI sequence and populate some default # values in backend input. Note that not all these screens # will be displayed as they have conditional to skip them at # the start of each function. In future these conditionals will # be moved into the sequence definition and evaluated by the # UI dispatcher. aborted = False if ui and interactive: uiexit = ui.installer.runMainSequence(results, ram_warning, vt_warning, suppress_extra_cd_dialog) if uiexit == uicontroller.EXIT: aborted = True if not aborted: if results['install-type'] == constants.INSTALL_TYPE_RESTORE: xelogging.log('INPUT ANSWER DICTIONARY') backend.prettyLogAnswers(results) xelogging.log("SCRIPTS DICTIONARY:") backend.prettyLogAnswers(scripts.script_dict) xelogging.log("Starting actual restore") backup = results['backup-to-restore'] if ui: pd = tui.progress.initProgressDialog( "Restoring %s" % backup, "Restoring data - this may take a while...", 100) def progress(x): if ui and pd: tui.progress.displayProgressDialog(x, pd) restore.restoreFromBackup(backup, progress) if ui: tui.progress.clearModelessDialog() tui.progress.OKDialog( "Restore", "The restore operation completed successfully.") else: xelogging.log("Starting actual installation") backend.performInstallation(results, ui, interactive) if ui and interactive: ui.installer.screens.installation_complete() xelogging.log("The installation completed successfully.") else: xelogging.log( "The user aborted the installation from within the user interface." ) status = constants.EXIT_USER_CANCEL
def confirm_load_drivers(answers): # find drivers: try: tui.progress.showMessageDialog("Please wait", "Searching for drivers...") repos = repository.repositoriesFromDefinition( answers['source-media'], answers['source-address']) tui.progress.clearModelessDialog() except: ButtonChoiceWindow( tui.screen, "Error", """Unable to access location specified. Please check the address was valid and/or that the media was inserted correctly, and try again.""", ['Back']) return LEFT_BACKWARDS drivers = [] id_list = [] for r in repos: has_drivers = False for p in r: if p.type.startswith("driver"): if p.is_compatible(): has_drivers = True else: xelogging.log("Driver %s is not compatible, skipping" % p.name) if has_drivers: drivers.append(p) id_list.append(r.identifier()) if len(drivers) == 0: ButtonChoiceWindow( tui.screen, "No Drivers Found", """No compatible drivers were found at the location specified. Please check the address was valid and/or that the media was inserted correctly, and try again. Note that this driver-loading mechanism is only compatible with media/locations containing %s repositories. Check the installation guide for more information.""" % (PRODUCT_BRAND or PLATFORM_NAME), ['Back'], width = 50) return LEFT_BACKWARDS else: if len(drivers) == 1: text = "The following driver was found:\n\n" elif len(drivers) > 1: text = "The following drivers were found:\n\n" for d in drivers: text += " * %s\n" % d.name while True: rc = ButtonChoiceWindow( tui.screen, "Load Drivers", text, ['Load drivers', 'Info', 'Back']) if rc == 'back': return LEFT_BACKWARDS elif rc == 'info': hashes = [" %s %s" % (r.md5sum(), r.name()) for r in repos] text2 = "The following MD5 hashes have been calculated. Please check them against those provided by the driver supplier:\n\n" text2 += "\n".join(hashes) ButtonChoiceWindow( tui.screen, "Driver Repository Information", text2, ['Ok']) else: break answers['repos'] = repos answers['id-list'] = id_list return RIGHT_FORWARDS
def go(ui, args, answerfile_address, answerfile_script): extra_repo_defs = [] results = { 'keymap': None, 'serial-console': None, 'operation': init_constants.OPERATION_INSTALL, 'boot-serial': False, 'extra-repos': [], 'network-backend': constants.NETWORK_BACKEND_DEFAULT, } suppress_extra_cd_dialog = False serial_console = None boot_console = None boot_serial = False if not xen_control_domain() or args.has_key('--virtual'): hardware.useVMHardwareFunctions() for (opt, val) in args.items(): if opt == "--boot-console": # takes precedence over --console if hardware.is_serialConsole(val): boot_console = hardware.getSerialConfig() elif opt == "--console": for console in val: if hardware.is_serialConsole(console): serial_console = hardware.getSerialConfig() if hardware.is_serialConsole(val[-1]): boot_serial = True elif opt == "--keymap": results["keymap"] = val xelogging.log("Keymap specified on command-line: %s" % val) elif opt == "--extrarepo": extra_repo_defs += val elif opt == "--onecd": suppress_extra_cd_dialog = True elif opt == "--disable-gpt": constants.GPT_SUPPORT = False if boot_console and not serial_console: serial_console = boot_console boot_serial = True if serial_console: try: results['serial-console'] = hardware.SerialPort.from_string(serial_console) results['boot-serial'] = boot_serial xelogging.log("Serial console specified on command-line: %s, default boot: %s" % (serial_console, boot_serial)) except: pass interactive = True try: # loading an answerfile? assert ui != None or answerfile_address != None or answerfile_script != None if answerfile_address and answerfile_script: raise RuntimeError, "Both answerfile and answerfile generator passed on command line." a = None if answerfile_address: a = answerfile.Answerfile(answerfile_address) elif answerfile_script: a = answerfile.Answerfile.generate(answerfile_script) if a: interactive = False results['network-hardware'] = netutil.scanConfiguration() results.update(a.parseScripts()) results.update(a.processAnswerfile()) if results.has_key('extra-repos'): # load drivers now for d in results['extra-repos']: media, address, _ = d for r in repository.repositoriesFromDefinition(media, address): for p in r: if p.type.startswith('driver'): if p.load() != 0: raise RuntimeError, "Failed to load driver %s." % p.name results['extra-repos'] += extra_repo_defs xelogging.log("Driver repos: %s" % str(results['extra-repos'])) scripts.run_scripts('installation-start') # log the modules that we loaded: xelogging.log("All needed modules should now be loaded. We have loaded:") util.runCmd2(["/bin/lsmod"]) status = constants.EXIT_OK # debug: print out what disks have been discovered diskutil.log_available_disks() # how much RAM do we have? ram_found_mb = hardware.getHostTotalMemoryKB() / 1024 ram_warning = ram_found_mb < constants.MIN_SYSTEM_RAM_MB vt_warning = not hardware.VTSupportEnabled() # Generate the UI sequence and populate some default # values in backend input. Note that not all these screens # will be displayed as they have conditional to skip them at # the start of each function. In future these conditionals will # be moved into the sequence definition and evaluated by the # UI dispatcher. aborted = False if ui and interactive: uiexit = ui.installer.runMainSequence( results, ram_warning, vt_warning, suppress_extra_cd_dialog ) if uiexit == uicontroller.EXIT: aborted = True if not aborted: if results['install-type'] == constants.INSTALL_TYPE_RESTORE: xelogging.log("Starting actual restore") backup = results['backup-to-restore'] if ui: pd = tui.progress.initProgressDialog("Restoring", "Restoring data - this may take a while...", 100) def progress(x): if ui and pd: tui.progress.displayProgressDialog(x, pd) restore.restoreFromBackup(backup.partition, backup.root_disk, progress) if pd: tui.progress.clearModelessDialog() tui.progress.OKDialog("Restore", "The restore operation completed successfully.") else: xelogging.log("Starting actual installation") results = backend.performInstallation(results, ui, interactive) if ui and interactive: ui.installer.screens.installation_complete() xelogging.log("The installation completed successfully.") else: xelogging.log("The user aborted the installation from within the user interface.") status = constants.EXIT_USER_CANCEL except Exception, e: try: # first thing to do is to get the traceback and log it: ex = sys.exc_info() err = str.join("", traceback.format_exception(*ex)) xelogging.log("INSTALL FAILED.") xelogging.log("A fatal exception occurred:") xelogging.log(err) # run the user's scripts - an arg of "1" indicates failure scripts.run_scripts('installation-complete', '1') # collect logs where possible xelogging.collectLogs("/tmp") # now display a friendly error dialog: if ui: ui.exn_error_dialog("install-log", True, interactive) else: txt = constants.error_string(str(e), 'install-log', True) xelogging.log(txt) # and now on the disk if possible: if 'primary-disk' in results and 'primary-partnum' in results: backend.writeLog(results['primary-disk'], results['primary-partnum']) xelogging.log(results) except Exception, e: # Don't let logging exceptions prevent subsequent actions print 'Logging failed: '+str(e)