def parseFCoEInterface(self): results = {} nethw = netutil.scanConfiguration() for interface in getElementsByTagName(self.top_node, ['fcoe-interface']): if_hwaddr = None if 'fcoe-interfaces' not in results: results['fcoe-interfaces'] = {} if_name = getStrAttribute(interface, ['name']) if if_name and if_name in nethw: if_hwaddr = nethw[if_name].hwaddr else: if_hwaddr = getStrAttribute(interface, ['hwaddr']) if if_hwaddr: matching_list = filter(lambda x: x.hwaddr == if_hwaddr.lower(), nethw.values()) if len(matching_list) == 1: if_name = matching_list[0].name if not if_name and not if_hwaddr: raise AnswerfileException("<fcoe-interface> tag must have one of 'name' or 'hwaddr'") dcb = getStrAttribute(interface, ['dcb']) if dcb in ['on', 'yes', 'true', '1', 'enable']: dcb_state = True elif dcb in ['off', 'no', 'false', '0', 'disable']: dcb_state = False else: # by default dcb is on dcb_state = True results['fcoe-interfaces'][if_name] = dcb_state return results
def main(args): results = {} dests = [] ui = None xelogging.openLog('/dev/tty3') if len(args) == 0: ui = tui else: dests = args if ui: ui.init_ui() results['network-hardware'] = netutil.scanConfiguration() local_dest = lambda a: a['dest-media'] == 'local' remote_dest = lambda a: a['dest-media'] != 'local' seq = [ uicontroller.Step(select_report_media), uicontroller.Step(tui.network.requireNetworking, predicates=[remote_dest]), uicontroller.Step(get_local_disk, predicates=[local_dest]), uicontroller.Step(select_report_dest), ] rc = uicontroller.runSequence(seq, results) if rc == uicontroller.RIGHT_FORWARDS: xelogging.log("ANSWERS DICTIONARY:") xelogging.log(str(results)) if results['dest-media'] == 'local': dests.append("dev://" + results['dest-address']) elif results['dest-media'] == 'ftp': dests.append(results['dest-address']) elif results['dest-media'] == 'nfs': dests.append("nfs://" + results['dest-address']) # create tarball collectLogs('/tmp', '/tmp') report_saved = False for dest in dests: xelogging.log("Saving report to: " + dest) try: a = xcp.accessor.createAccessor(dest, False) a.start() fh = open('/tmp/support.tar.bz2') a.writeFile(fh, 'support.tar.bz2') fh.close() a.finish() report_saved = True except Exception, e: xelogging.log("Failed: " + str(e)) report_saved = False
def main(args): results = {} dests = [] ui = None xelogging.openLog('/dev/tty3') if len(args) == 0: ui = tui else: dests = args if ui: ui.init_ui() results['network-hardware'] = netutil.scanConfiguration() local_dest = lambda a: a['dest-media'] == 'local' remote_dest = lambda a: a['dest-media'] != 'local' seq = [ uicontroller.Step(select_report_media), uicontroller.Step(tui.network.requireNetworking, predicates = [remote_dest]), uicontroller.Step(get_local_disk, predicates = [local_dest]), uicontroller.Step(select_report_dest), ] rc = uicontroller.runSequence(seq, results) if rc == uicontroller.RIGHT_FORWARDS: xelogging.log("ANSWERS DICTIONARY:") xelogging.log(str(results)) if results['dest-media'] == 'local': dests.append("dev://" + results['dest-address']) elif results['dest-media'] == 'ftp': dests.append(results['dest-address']) elif results['dest-media'] == 'nfs': dests.append("nfs://" + results['dest-address']) # create tarball collectLogs('/tmp', '/tmp') report_saved = False for dest in dests: xelogging.log("Saving report to: " + dest) try: a = xcp.accessor.createAccessor(dest, False) a.start() fh = open('/tmp/support.tar.bz2') a.writeFile(fh, 'support.tar.bz2') fh.close() a.finish() report_saved = True except Exception, e: xelogging.log("Failed: " + str(e)) report_saved = False
def parseInterface(self): results = {} node = getElementsByTagName(self.top_node, ['admin-interface'], mandatory=True)[0] nethw = netutil.scanConfiguration() if_hwaddr = None if_name = getStrAttribute(node, ['name']) if if_name and if_name in nethw: if_hwaddr = nethw[if_name].hwaddr else: if_hwaddr = getStrAttribute(node, ['hwaddr']) if if_hwaddr: matching_list = filter(lambda x: x.hwaddr == if_hwaddr.lower(), nethw.values()) if len(matching_list) == 1: if_name = matching_list[0].name if not if_name and not if_hwaddr: raise AnswerfileException("<admin-interface> tag must have one of 'name' or 'hwaddr'") results['net-admin-interface'] = if_name proto = getStrAttribute(node, ['proto'], mandatory=True) if proto == 'static': ip = getText(getElementsByTagName(node, ['ip', 'ipaddr'], mandatory=True)[0]) subnet = getText(getElementsByTagName(node, ['subnet-mask', 'subnet'], mandatory=True)[0]) gateway = getText(getElementsByTagName(node, ['gateway'], mandatory=True)[0]) results['net-admin-configuration'] = NetInterface(NetInterface.Static, if_hwaddr, ip, subnet, gateway, dns=None) elif proto == 'dhcp': results['net-admin-configuration'] = NetInterface(NetInterface.DHCP, if_hwaddr) else: results['net-admin-configuration'] = NetInterface(None, if_hwaddr) protov6 = getStrAttribute(node, ['protov6']) if protov6 == 'static': ipv6 = getText(getElementsByTagName(node, ['ipv6'], mandatory=True)[0]) gatewayv6 = getText(getElementsByTagName(node, ['gatewayv6'], mandatory=True)[0]) results['net-admin-configuration'].addIPv6(NetInterface.Static, ipv6, gatewayv6) elif protov6 == 'dhcp': results['net-admin-configuration'].addIPv6(NetInterface.DHCP) elif protov6 == 'autoconf': results['net-admin-configuration'].addIPv6(NetInterface.Autoconf) vlan = getStrAttribute(node, ['vlan']) if vlan: if not netutil.valid_vlan(vlan): raise AnswerfileException("Invalid value for vlan attribute specified.") results['net-admin-configuration'].vlan = int(vlan) if not results['net-admin-configuration'].valid(): raise AnswerfileException("<admin-interface> tag must have IPv4 or IPv6 defined.") return results
def get_dcb_capable_ifaces(check_lun): ''' Return all dcb capable interfaces. if checkLun is True, then this routine will check if there are any LUNs associated with an interface and will exclued them from the dictonary that is returned. ''' start_lldpad() dcb_nics = {} nics = netutil.scanConfiguration() def get_dcb_capablity(interface): ''' checks if a NIC is dcb capable. If netdev for an interface has dcbnl_ops defined then this interface is deemed dcb capable. dcbtool gc ethX dcb will return Status = Successful if netdev has dcbnl_ops defined. ''' output = None rc, output, err = util.runCmd2(['dcbtool', 'gc', interface, 'dcb'], True, True) if rc != 0: return False if output is not None: outlist = output.split('\n') outstr = outlist[3] outdata = outstr.split(':') if "Successful" in outdata[1]: return True else: return False for nic, conf in nics.iteritems(): if get_dcb_capablity(nic): if check_lun and len(get_luns_on_intf(nic)) > 0: continue if netutil.getDriver(nic) == 'bnx2x': # These nics are capable of doing dcb in hardware dcb_nics[nic] = False else: dcb_nics[nic] = True return dcb_nics
def parseInterfaces(self): """ Parse the admin-interface element. This has either name="eth0" or hwaddr="x:y:z.." to identify the interface to use, then an IP configuration which is either proto="dhcp" or proto="static" ip="..." subnet-mask="..." gateway="..." dns="...".""" results = {} netifnode = self.nodelist.getElementsByTagName('admin-interface')[0] # allow interfaces to be specified by either hardware address or name - find # out the value to both variables: nethw = netutil.scanConfiguration() requested_hwaddr = None requested_name = None if netifnode.getAttribute('name'): requested_name = netifnode.getAttribute('name') if nethw.has_key(requested_name): requested_hwaddr = nethw[requested_name].hwaddr else: raise AnswerfileError, "Interface %s not found." % requested_name elif netifnode.getAttribute('hwaddr'): requested_hwaddr = netifnode.getAttribute('hwaddr').lower() # work out which device corresponds to the hwaddr we were given: matching_list = filter(lambda x: x.hwaddr == requested_hwaddr, nethw.values()) if len(matching_list) == 1: requested_name = matching_list[0].name else: raise AnswerfileError, "%d interfaces matching the MAC specified for the management interface." % (len(matching_list)) assert requested_name and requested_hwaddr results['net-admin-interface'] = requested_name proto = netifnode.getAttribute('proto') if proto == 'static': ip = getText(netifnode.getElementsByTagName('ip')[0].childNodes) subnetmask = getText(netifnode.getElementsByTagName('subnet-mask')[0].childNodes) gateway = getText(netifnode.getElementsByTagName('gateway')[0].childNodes) results['net-admin-configuration'] = NetInterface(NetInterface.Static, requested_hwaddr, ip, subnetmask, gateway, dns=None) elif proto == 'dhcp': results['net-admin-configuration'] = NetInterface(NetInterface.DHCP, requested_hwaddr) else: raise AnswerfileError, "<admin-interface> tag must have attribute proto='static' or proto='dhcp'." return results
def configureNetworking(device, config): if device == 'all': config = 'dhcp' config_dict = None try: if config.startswith('static:'): config_dict = {'gateway': None, 'dns': None, 'domain': None} for el in config[7:].split(';'): k, v = el.split('=', 1) config_dict[k] = v if 'dns' in config_dict: config_dict['dns'] = config_dict['dns'].split(',') assert 'ip' in config_dict and 'netmask' in config_dict except: pass nethw = netutil.scanConfiguration() netcfg = {} for i in nethw.keys(): if (device == i or device == nethw[i].hwaddr) and config_dict: netcfg[i] = NetInterface(NetInterface.Static, nethw[i].hwaddr, config_dict['ip'], config_dict['netmask'], config_dict['gateway'], config_dict['dns'], config_dict['domain']) else: netcfg[i] = NetInterface(NetInterface.DHCP, nethw[i].hwaddr) netutil.writeNetInterfaceFiles(netcfg) netutil.writeResolverFile(netcfg, '/etc/resolv.conf') if device == 'all': for i in nethw.keys(): netutil.ifup(i) elif device.startswith('eth'): if nethw.has_key(device): netutil.ifup(device) else: # MAC address matching_list = filter(lambda x: x.hwaddr == device, nethw.values()) if len(matching_list) == 1: netutil.ifup(matching_list[0].name)
def configureNetworking(device, config): if device == 'all': config = 'dhcp' config_dict = None try: if config.startswith('static:'): config_dict = {'gateway': None, 'dns': None, 'domain': None} for el in config[7:].split(';'): k, v = el.split('=', 1) config_dict[k] = v if 'dns' in config_dict: config_dict['dns'] = config_dict['dns'].split(',') assert 'ip' in config_dict and 'netmask' in config_dict except: pass nethw = netutil.scanConfiguration() netcfg = {} for i in nethw.keys(): if (device == i or device == nethw[i].hwaddr) and config_dict: netcfg[i] = NetInterface(NetInterface.Static, nethw[i].hwaddr, config_dict['ip'], config_dict['netmask'], config_dict['gateway'], config_dict['dns'], config_dict['domain']) else: netcfg[i] = NetInterface(NetInterface.DHCP, nethw[i].hwaddr) netutil.writeDebStyleInterfaceFile(netcfg, '/etc/network/interfaces') netutil.writeResolverFile(netcfg, '/etc/resolv.conf') if device == 'all': for i in nethw.keys(): netutil.ifup(i) elif device.startswith('eth'): if nethw.has_key(device): netutil.ifup(device) else: # MAC address matching_list = filter(lambda x: x.hwaddr == device, nethw.values()) if len(matching_list) == 1: netutil.ifup(matching_list[0].name)
def get_fcoe_capable_ifaces(check_lun): ''' Return all FCoE capable interfaces. if checkLun is True, then this routine will check if there are any LUNs associated with an interface and will exclued them from the list that is returned. ''' start_lldpad() dcb_nics = [] nics = netutil.scanConfiguration() def get_dcb_capablity(interface): ''' checks if a NIC is dcb capable (in hardware or software). If netdev for an interface has dcbnl_ops defined then this interface is deemed dcb capable. dcbtool gc ethX dcb will return Status = Successful if netdev has dcbnl_ops defined. ''' output = None rc, output, err = util.runCmd2(['dcbtool', 'gc', interface, 'dcb'], True, True) if rc != 0: return False if output is not None: outlist = output.split('\n') outstr = outlist[3] outdata = outstr.split(':') return "Successful" in outdata[1] for nic, conf in nics.iteritems(): if get_dcb_capablity(nic): if check_lun and len(get_luns_on_intf(nic)) > 0: continue dcb_nics.append(nic) return dcb_nics
def setup_ibft_nics(): mac_map = {} netdevs = netutil.scanConfiguration() for name in netdevs: mac_map[netdevs[name].hwaddr] = name xelogging.log('NET: %s %s' % (repr(netdevs), repr(mac_map))) for t in glob.glob(os.path.join(constants.SYSFS_IBFT_DIR, 'target*')): with open(os.path.join(t, 'ip-addr'), 'r') as f: target_ip = f.read().strip() with open(os.path.join(t, 'nic-assoc'), 'r') as f: nic_assoc = f.read().strip() e_dir = os.path.join(constants.SYSFS_IBFT_DIR, 'ethernet' + nic_assoc) with open(os.path.join(e_dir, 'mac'), 'r') as f: mac = f.read().strip() with open(os.path.join(e_dir, 'ip-addr'), 'r') as f: ip = f.read().strip() try: with open(os.path.join(e_dir, 'gateway'), 'r') as f: gw = f.read().strip() except IOError as e: if e.errno == errno.ENOENT: gw = None else: raise with open(os.path.join(e_dir, 'subnet-mask'), 'r') as f: nm = f.read().strip() with open(os.path.join(e_dir, 'flags'), 'r') as f: flags = int(f.read().strip()) assert (flags & 3) == 3 if mac not in mac_map: raise RuntimeError( 'Found mac %s in iBFT but cannot find matching NIC' % mac) configure_ibft_nic(target_ip, mac_map[mac], ip, nm, gw) ibft_reserved_nics.add(mac_map[mac])
def parseFCoEInterface(self): results = {} nethw = netutil.scanConfiguration() for interface in getElementsByTagName(self.top_node, ['fcoe-interface']): if_hwaddr = None if 'fcoe-interfaces' not in results: results['fcoe-interfaces'] = [] if_name = getStrAttribute(interface, ['name']) if if_name and if_name in nethw: if_hwaddr = nethw[if_name].hwaddr else: if_hwaddr = getStrAttribute(interface, ['hwaddr']) if if_hwaddr: matching_list = filter(lambda x: x.hwaddr == if_hwaddr.lower(), nethw.values()) if len(matching_list) == 1: if_name = matching_list[0].name if not if_name and not if_hwaddr: raise AnswerfileException("<fcoe-interface> tag must have one of 'name' or 'hwaddr'") results['fcoe-interfaces'].append(if_name) return results
def welcome_screen(answers): driver_answers = {'driver-repos': []} tui.update_help_line([None, "<F9> load driver"]) def load_driver(driver_answers): tui.screen.popHelpLine() tui.update_help_line([None, ' ']) drivers = driver.doInteractiveLoadDriver(tui, driver_answers) xelogging.log(drivers) xelogging.log(driver_answers) if drivers[0]: if 'extra-repos' not in answers: answers['extra-repos'] = [] answers['extra-repos'].append(drivers) return True global loop global popup loop = True def fn9(): global loop global popup loop = True popup = 'driver' return False def fn10(): global loop global popup loop = True popup = 'storage' return False while loop: loop = False popup = None driver_answers['network-hardware'] = answers['network-hardware'] = netutil.scanConfiguration() button = snackutil.ButtonChoiceWindowEx(tui.screen, "Welcome to %s Setup" % MY_PRODUCT_BRAND, """This setup tool can be used to install or upgrade %s on your system or restore your server from backup. Installing %s will erase all data on the disks selected for use. Please make sure you have backed up any data you wish to preserve before proceeding. To load a device driver press <F9>. To setup advanced storage classes press <F10>. """ % (MY_PRODUCT_BRAND, MY_PRODUCT_BRAND), ['Ok', 'Reboot'], width = 60, help = "welcome", hotkeys = {'F9': fn9, 'F10': fn10}) if popup == 'driver': load_driver(driver_answers) tui.update_help_line([None, "<F9> load driver"]) elif popup == 'storage': tui.fcoe.select_fcoe_ifaces(answers) tui.update_help_line([None, "<F9> load driver"]) tui.screen.popHelpLine() if button == 'reboot': return EXIT xelogging.log("Waiting for partitions to appear...") util.runCmd2(util.udevsettleCmd()) time.sleep(1) diskutil.mpath_part_scan() # ensure partitions/disks are not locked by LVM lvm = LVMTool() lvm.deactivateAll() del lvm tui.progress.showMessageDialog("Please wait", "Checking for existing products...") answers['installed-products'] = product.find_installed_products() answers['upgradeable-products'] = upgrade.filter_for_upgradeable_products(answers['installed-products']) answers['backups'] = product.findXenSourceBackups() tui.progress.clearModelessDialog() diskutil.log_available_disks() # CA-41142, ensure we have at least one network interface and one disk before proceeding label = None if len(diskutil.getDiskList()) == 0: label = "No Disks" text = "hard disks" text_short = "disks" if len(answers['network-hardware'].keys()) == 0: label = "No Network Interfaces" text = "network interfaces" text_short = "interfaces" if label: text = """This host does not appear to have any %s. If %s are present you may need to load a device driver on the previous screen for them to be detected.""" % (text, text_short) ButtonChoiceWindow(tui.screen, label, text, ["Back"], width = 48) return REPEAT_STEP 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 '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 select_fcoe_ifaces(answers): """ Display a screen that displays all network interfaces that are FCoE-capable and allows the user to select one or more. """ conf = netutil.scanConfiguration() fcoe_ifaces = fcoeutil.get_dcb_capable_ifaces(True) if len(fcoe_ifaces) == 0: button = ButtonChoiceWindow(tui.screen, "FCoE Interfaces", "No DCB capable interfaces found", ['Back'], width=60) return netifs = fcoe_ifaces.keys() netifs.sort(lambda l, r: int(l[3:]) - int(r[3:])) def iface_details(context): tui.update_help_line([' ', ' ']) nic = conf[context] table = [("Name:", nic.name), ("Driver:", nic.driver), ("MAC Address:", nic.hwaddr), ("Link Status:", netutil.linkUp(context) and 'Up' or 'Down')] snackutil.TableDialog(tui.screen, "Interface Details", *table) tui.screen.popHelpLine() return True # Map between soft/off and soft/hard (depending on interface property) def dcb_state_label(iface, state): if state: return '[soft]' if not fcoe_ifaces[iface]: return '[hard]' return ' ' if 'fcoe-interfaces' not in answers: answers['fcoe-interfaces'] = {} entries = {} for ne in netifs: state = dcb_state_label( ne, answers['fcoe-interfaces'].get(ne, fcoe_ifaces[ne])) entry = "%s %s" % (ne, state) entries[ne] = entry text = TextboxReflowed(54, "Select one or more interfaces to setup for FCoE.") buttons = ButtonBar(tui.screen, [('Ok', 'ok'), ('DCB', 'dcb'), ('Back', 'back')]) scroll, _ = snackutil.scrollHeight(3, len(entries.keys())) cbt = CheckboxTree(3, scroll) for iface in netifs: cbt.append(entries[iface], iface, iface in answers['fcoe-interfaces']) gf = GridFormHelp(tui.screen, 'FCoE Interfaces', 'fcoeiface:info', 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.addHotKey('F5') tui.update_help_line([None, "<F5> more info"]) loop = True while loop: rc = gf.run() if rc == 'F5': iface_details(cbt.getCurrent()) elif buttons.buttonPressed(rc) == 'dcb': ne = cbt.getCurrent() new = dcb_state_label(ne, not entries[ne].endswith('[soft]')) entries[ne] = "%s %s" % (ne, new) cbt.setEntry(ne, entries[ne]) else: loop = False tui.screen.popWindow() tui.screen.popHelpLine() button = buttons.buttonPressed(rc) if button == 'back': return r = dict( map(lambda (k): (k, entries[k].endswith('[soft]')), cbt.getSelection())) answers['fcoe-interfaces'] = r xelogging.log("Selected fcoe interfaces %s" % str(r)) tui.update_help_line([' ', ' ']) # Bring up FCoE devices tui.progress.showMessageDialog("Please wait", "Discovering devices...") result = fcoeutil.start_fcoe(answers['fcoe-interfaces']) xelogging.log("fcoe result %s" % str(result)) tui.progress.clearModelessDialog() fail = {k: v for k, v in result.iteritems() if v != 'OK'} if len(fail.keys()) > 0: # Report any errors err_text = '\n'.join( map(lambda (x, y): "%s %s" % (x, y), fail.iteritems())) text = TextboxReflowed( 60, "The following errors occured while discovering FCoE disks.") errs = Textbox(30, 6, err_text, scroll=len(fail.keys()) > 6) buttons = ButtonBar(tui.screen, [('Ok', 'ok')]) gf = GridFormHelp(tui.screen, 'Discovery Failure', 'fipvlanfail', 1, 3) gf.add(text, 0, 0, padding=(0, 0, 0, 1)) gf.add(errs, 0, 1, padding=(0, 0, 0, 1)) gf.add(buttons, 0, 2, growx=1) gf.run() tui.screen.popWindow() # Get the results and build a dict of LUNs d = fcoeutil.get_fcoe_luns() luns = {} for k, v in d.items(): for k2, v2 in v.items(): for lun in v2['luns'].values(): luns[os.path.basename(lun['device'])] = { 'Capacity': lun['capacity'], 'Description': lun['description'], 'Port': v2['Port Name'], 'VLAN': k } xelogging.log("fcoe luns discovered %s" % str(luns)) def disk_details(context): tui.update_help_line([' ', ' ']) table = [("Name:", context)] for label in ("VLAN", "Capacity", "Port", "Description"): table.append((label + ':', luns[context][label])) snackutil.TableDialog(tui.screen, "Disk Details", *table) tui.screen.popHelpLine() return True if len(luns.keys()) > 0: disk_list = [] for lun in sorted(luns.keys()): disk_list.append(("%s - %s" % (lun, luns[lun]['Capacity']), lun)) tui.update_help_line([None, "<F5> more info"]) scroll, height = snackutil.scrollHeight(6, len(disk_list)) snackutil.ListboxChoiceWindowEx( tui.screen, "FCoE Disks", "The following devices are now available.", disk_list, ['Ok'], 45, scroll, height, None, help='fcoedisks:info', hotkeys={'F5': disk_details}) tui.screen.popHelpLine()
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 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)
def welcome_screen(answers): driver_answers = {'loaded-drivers': [], 'driver-repos': []} tui.update_help_line([None, "<F9> load driver"]) def load_driver(driver_answers): tui.screen.popHelpLine() tui.update_help_line([None, ' ']) drivers = driver.doInteractiveLoadDriver(tui, driver_answers) xelogging.log(drivers) xelogging.log(driver_answers) if drivers[0]: if 'extra-repos' not in answers: answers['extra-repos'] = [] answers['extra-repos'].append(drivers) return True global loop loop = True def fn9(): global loop loop = True return False while loop: loop = False driver_answers['network-hardware'] = answers['network-hardware'] = netutil.scanConfiguration() button = snackutil.ButtonChoiceWindowEx(tui.screen, "Welcome to %s Setup" % MY_PRODUCT_BRAND, """This setup tool can be used to install or upgrade %s on your system or restore your server from backup. Installing %s will erase all data on the disks selected for use. Please make sure you have backed up any data you wish to preserve before proceeding. To load a device driver press <F9>. """ % (MY_PRODUCT_BRAND, MY_PRODUCT_BRAND), ['Ok', 'Reboot'], width = 60, help = "welcome", hotkey = 'F9', hotkey_cb = fn9) if loop: load_driver(driver_answers) tui.update_help_line([None, "<F9> load driver"]) tui.screen.popHelpLine() if button == 'reboot': return EXIT # CA-41142, ensure we have at least one network interface and one disk before proceeding label = None if len(diskutil.getDiskList()) == 0: label = "No Disks" text = "hard disks" text_short = "disks" if len(answers['network-hardware'].keys()) == 0: label = "No Network Interfaces" text = "network interfaces" text_short = "interfaces" if label: text = """This host does not appear to have any %s. If %s are present you may need to load a device driver on the previous screen for them to be detected.""" % (text, text_short) ButtonChoiceWindow(tui.screen, label, text, ["Back"], width = 48) return REPEAT_STEP return RIGHT_FORWARDS