def doInteractiveLoadDriver(ui, answers): media = None address = None required_repo_list = [] loaded_drivers = [] rc = ui.init.driver_disk_sequence(answers, answers['driver-repos']) if rc: media, address = rc repos = answers['repos'] # now load the drivers: for r in repos: logger.log("Processing repo %s" % r) try: r.installPackages(lambda x: (), {'root': '/'}) answers['driver-repos'].append(str(r)) ButtonChoiceWindow(ui.screen, "Drivers Loaded", "Loaded %s." % r.name(), ['Ok']) except Exception as e: logger.logException(e) ButtonChoiceWindow( ui.screen, "Problem Loading Driver", "Setup was unable to load the device driver.", ['Ok']) return media, address
def parentdev_from_devpath(devpath): """Returns the dev number of the parent device, or None if there isn't one.""" try: devno = os.stat(devpath).st_rdev major = os.major(devno) minor = os.minor(devno) syspath = '/sys/dev/block/%d:%d' % (major, minor) partitionpath = syspath + '/partition' if os.path.exists(partitionpath): linkpath = os.path.realpath(syspath) parent = os.path.dirname(linkpath) return dev_from_sysfs(parent) else: dm_uuidpath = syspath + '/dm/uuid' if os.path.exists(dm_uuidpath): with open(dm_uuidpath, 'r') as f: dm_uuid = f.read().strip() if re.match('part[0-9+]-', dm_uuid): parent = os.listdir(syspath + '/slaves')[0] return dev_from_sysfs('%s/slaves/%s' % (syspath, parent)) except Exception as e: logger.logException(e) # If there is no parent of the parent cannot be determined... return None
def findXenSourceProducts(): """Scans the host and finds XenSource product installations. Returns list of ExistingInstallation objects. Currently requires supervisor privileges due to mounting filesystems.""" installs = [] for disk in diskutil.getQualifiedDiskList(): (boot, root, state, storage, logs) = diskutil.probeDisk(disk) inst = None try: if root[0] == diskutil.INSTALL_RETAIL: inst = ExistingRetailInstallation(disk, boot[1], root[1], state[1], storage) except Exception as e: logger.log( "A problem occurred whilst scanning for existing installations:" ) logger.logException(e) logger.log("This is not fatal. Continuing anyway.") if inst: logger.log("Found an installation: %s on %s" % (str(inst), disk)) installs.append(inst) return installs
def __init__(self, accessor): YumRepository.__init__(self, accessor) accessor.start() try: updatefp = accessor.openAddress(self.INFO_FILENAME) try: dom = xml.dom.minidom.parseString(updatefp.read()) except Exception as e: logger.logException(e) raise RepoFormatError("Failed to read %s: %s" % (self.INFO_FILENAME, str(e))) finally: updatefp.close() assert dom.documentElement.tagName == 'update' self._controlpkg = dom.documentElement.getAttribute('control') self._identifier = dom.documentElement.getAttribute('name-label') self._targets = [self._controlpkg, 'update-' + self._identifier] except Exception as e: accessor.finish() logger.logException(e) raise RepoFormatError("Failed to read %s: %s" % (self.INFO_FILENAME, str(e))) self._parse_repodata(accessor) accessor.finish()
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: logger.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 inject_to_vif(self, vif): mac = get_vif_mac(vif) try: self.inject_packet(vif, mac) log.info('Inject IGMP query to vif:%s, mac:%s' % (vif, mac)) except Exception as e: log.error('Inject IGMP query to vif:%s, mac:%s failed' % (vif, mac)) log.logException(e)
def find_installed_products(): try: installed_products = findXenSourceProducts() except Exception as e: logger.log( "A problem occurred whilst scanning for existing installations:") logger.logException(e) logger.log("This is not fatal. Continuing anyway.") installed_products = [] return installed_products
def copy_ownership(src_root, src_path, dst_root, dst_path): st = os.lstat('%s/%s' % (src_root, src_path)) try: new_uid = dst_uid_map[src_uid_map[st.st_uid]] new_gid = dst_gid_map[src_gid_map[st.st_gid]] except IndexError as e: logger.error('Failed to copy ownership') logger.logException(e) return if st.st_uid != new_uid or st.st_gid != new_gid: os.lchown('%s/%s' % (dst_root, dst_path), new_uid, new_gid)
def settingsAvailable(self): try: self.readSettings() except SettingsNotAvailable as text: logger.log("Settings unavailable: %s" % text) return False except Exception as e: logger.log("Settings unavailable: unhandled exception") logger.logException(e) return False else: return True
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 __init__(self, accessor): YumRepository.__init__(self, accessor) self.keyfiles = [] accessor.start() try: treeinfo = ConfigParser.SafeConfigParser() treeinfofp = accessor.openAddress(self.INFO_FILENAME) try: treeinfo.readfp(treeinfofp) except Exception as e: raise RepoFormatError("Failed to read %s: %s" % (self.INFO_FILENAME, str(e))) finally: treeinfofp.close() if treeinfo.has_section('platform'): self._platform_name = treeinfo.get('platform', 'name') ver_str = treeinfo.get('platform', 'version') self._platform_version = Version.from_string(ver_str) if treeinfo.has_section('branding'): self._product_brand = treeinfo.get('branding', 'name') ver_str = treeinfo.get('branding', 'version') self._product_version = Version.from_string(ver_str) if treeinfo.has_section('build'): self._build_number = treeinfo.get('build', 'number') else: self._build_number = None if treeinfo.has_section('keys'): for _, keyfile in treeinfo.items('keys'): self.keyfiles.append(keyfile) except Exception as e: accessor.finish() logger.logException(e) raise RepoFormatError("Failed to read %s: %s" % (self.INFO_FILENAME, str(e))) self._parse_repodata(accessor) accessor.finish()
def init_id_maps(src_root, dst_root): """ Create mappings between (username and uid), and (group and gid) for the source and destination roots. """ with open(os.path.join(src_root, 'etc/passwd'), 'r') as f: for line in f: try: pwnam, _, uid, _ = line.split(':', 3) src_uid_map[int(uid)] = pwnam except ValueError as e: logger.error('Failed to parse: ' + line) logger.logException(e) with open(os.path.join(src_root, 'etc/group'), 'r') as f: for line in f: try: pwnam, _, gid, _ = line.split(':', 3) src_gid_map[int(gid)] = pwnam except ValueError as e: logger.error('Failed to parse: ' + line) logger.logException(e) with open(os.path.join(dst_root, 'etc/passwd'), 'r') as f: for line in f: try: pwnam, _, uid, _ = line.split(':', 3) dst_uid_map[pwnam] = int(uid) except ValueError as e: logger.error('Failed to parse: ' + line) logger.logException(e) with open(os.path.join(dst_root, 'etc/group'), 'r') as f: for line in f: try: pwnam, _, gid, _ = line.split(':', 3) dst_gid_map[pwnam] = int(gid) except ValueError as e: logger.error('Failed to parse: ' + line) logger.logException(e)
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 Exception as e: logger.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.""", ['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 _readSettings(self): """ Read settings from the installation, returns a results dictionary. """ results = {'host-config': {}} self.mount_state() try: # timezone: tz = None clock_file = self.join_state_path('etc/localtime') if os.path.islink(clock_file): tzfile = os.path.realpath(clock_file) if '/usr/share/zoneinfo/' in tzfile: _, tz = tzfile.split('/usr/share/zoneinfo/', 1) if not tz: # No timezone found: # Supply a default and for interactive installs prompt the user. logger.log('No timezone configuration found.') results['request-timezone'] = True tz = "Europe/London" results['timezone'] = tz # hostname. We will assume one was set anyway and thus write # it back into the new filesystem. If one wasn't set then this # will be localhost.localdomain, in which case the old behaviour # will persist anyway: fd = open(self.join_state_path('etc/sysconfig/network'), 'r') lines = fd.readlines() fd.close() for line in lines: if line.startswith('HOSTNAME='): results['manual-hostname'] = (True, line[9:].strip()) if os.path.exists(self.join_state_path('etc/hostname')): fd = open(self.join_state_path('etc/hostname'), 'r') line = fd.readline() results['manual-hostname'] = (True, line.strip()) fd.close() if 'manual-hostname' not in results: results['manual-hostname'] = (False, None) # nameservers: domain = None if not os.path.exists(self.join_state_path('etc/resolv.conf')): results['manual-nameservers'] = (False, None) else: ns = [] fd = open(self.join_state_path('etc/resolv.conf'), 'r') lines = fd.readlines() fd.close() for line in lines: if line.startswith("nameserver "): ns.append(line[11:].strip()) elif line.startswith("domain "): domain = line[8:].strip() elif line.startswith("search "): domain = line.split()[1] results['manual-nameservers'] = (True, ns) # ntp servers: if os.path.exists(self.join_state_path('etc/chrony.conf')): fd = open(self.join_state_path('etc/chrony.conf'), 'r') else: fd = open(self.join_state_path('etc/ntp.conf'), 'r') lines = fd.readlines() fd.close() ntps = [] for line in lines: if line.startswith("server "): ntps.append(line[7:].split()[0].strip()) results['ntp-servers'] = ntps # keyboard: keyboard_dict = {} keyboard_file = self.join_state_path('etc/sysconfig/keyboard') if os.path.exists(keyboard_file): keyboard_dict = util.readKeyValueFile(keyboard_file) keyboard_file = self.join_state_path('etc/vconsole.conf') if os.path.exists(keyboard_file): keyboard_dict.update(util.readKeyValueFile(keyboard_file)) if 'KEYMAP' in keyboard_dict: results['keymap'] = keyboard_dict['KEYMAP'] elif 'KEYTABLE' in keyboard_dict: results['keymap'] = keyboard_dict['KEYTABLE'] # Do not error here if no keymap configuration is found. # This enables upgrade to still carry state on hosts without # keymap configured: # A default keymap is assigned in the backend of this installer. if 'keymap' not in results: logger.log('No existing keymap configuration found.') # root password: fd = open(self.join_state_path('etc/passwd'), 'r') root_pwd = None for line in fd: pwent = line.split(':') if pwent[0] == 'root': root_pwd = pwent[1] break fd.close() if len(root_pwd) == 1: root_pwd = None try: fd = open(self.join_state_path('etc/shadow'), 'r') for line in fd: pwent = line.split(':') if pwent[0] == 'root': root_pwd = pwent[1] break fd.close() except: pass if not root_pwd: raise SettingsNotAvailable("no root password found") results['root-password'] = ('pwdhash', root_pwd) # don't care about this too much. results['time-config-method'] = 'ntp' # read network configuration. We only care to find out what the # management interface is, and what its configuration was. # The dev -> MAC mapping for other devices will be preserved in the # database which is available in time for everything except the # management interface. mgmt_iface = self.getInventoryValue('MANAGEMENT_INTERFACE') if not mgmt_iface: logger.log('No existing management interface found.') elif os.path.exists(self.join_state_path(constants.NETWORK_DB)): logger.log( 'Checking %s for management interface configuration' % constants.NETWORKD_DB) def fetchIfaceInfoFromNetworkdbAsDict(bridge, iface=None): args = [ 'chroot', self.state_fs.mount_point, '/' + constants.NETWORKD_DB, '-bridge', bridge ] if iface: args.extend(['-iface', iface]) rv, out = util.runCmd2(args, with_stdout=True) d = {} for line in (x.strip() for x in out.split('\n') if len(x.strip())): for key_value in line.split(" "): var = key_value.split('=', 1) d[var[0]] = var[1] return d d = fetchIfaceInfoFromNetworkdbAsDict(mgmt_iface, mgmt_iface) # For mgmt on tagged vlan, networkdb output has no value for # 'interfaces' but instead has 'parent' specified. We need # to fetch 'interfaces' of parent and use for mgmt bridge. if not d.get('interfaces') and 'parent' in d: p = fetchIfaceInfoFromNetworkdbAsDict(d['parent']) d['interfaces'] = p['interfaces'] results['net-admin-bridge'] = mgmt_iface results['net-admin-interface'] = d.get('interfaces').split( ',')[0] if_hwaddr = netutil.getHWAddr(results['net-admin-interface']) vlan = int(d['vlan']) if 'vlan' in d else None proto = d.get('mode') if proto == 'static': ip = d.get('ipaddr') netmask = d.get('netmask') gateway = d.get('gateway') dns = d.get('dns', '').split(',') if ip and netmask: results['net-admin-configuration'] = NetInterface( NetInterface.Static, if_hwaddr, ip, netmask, gateway, dns, vlan=vlan) elif proto == 'dhcp': results['net-admin-configuration'] = NetInterface( NetInterface.DHCP, if_hwaddr, vlan=vlan) else: results['net-admin-configuration'] = NetInterface( None, if_hwaddr, vlan=vlan) protov6 = d.get('modev6') if protov6 == 'static': ipv6 = d.get('ipaddrv6') gatewayv6 = d.get('gatewayv6') if ipv6: 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) repo_list = [] if os.path.exists( self.join_state_path(constants.INSTALLED_REPOS_DIR)): try: for repo_id in os.listdir( self.join_state_path( constants.INSTALLED_REPOS_DIR)): try: repo = repository.LegacyRepository( repository.FilesystemAccessor( self.join_state_path( constants.INSTALLED_REPOS_DIR, repo_id))) if repo.hidden() != "true": repo_list.append( (repo.identifier(), repo.name(), (repo_id != constants.MAIN_REPOSITORY_NAME))) except repository.RepoFormatError: # probably pre-XML format repo = open( self.join_state_path( constants.INSTALLED_REPOS_DIR, repo_id, repository.LegacyRepository. REPOSITORY_FILENAME)) repo_id = repo.readline().strip() repo_name = repo.readline().strip() repo.close() repo_list.append( (repo_id, repo_name, (repo_id != constants.MAIN_REPOSITORY_NAME))) except Exception as e: logger.log('Scan for driver disks failed:') logger.logException(e) results['repo-list'] = repo_list results['ha-armed'] = False try: db_path = "var/lib/xcp/local.db" if not os.path.exists(self.join_state_path(db_path)): db_path = "var/xapi/local.db" db = open(self.join_state_path(db_path), 'r') if db.readline().find( '<row key="ha.armed" value="true"') != -1: results['ha-armed'] = True db.close() except: pass try: network_conf = open( self.join_state_path("etc/xensource/network.conf"), 'r') network_backend = network_conf.readline().strip() network_conf.close() if network_backend == constants.NETWORK_BACKEND_BRIDGE: results[ 'network-backend'] = constants.NETWORK_BACKEND_BRIDGE elif network_backend in [ constants.NETWORK_BACKEND_VSWITCH, constants.NETWORK_BACKEND_VSWITCH_ALT ]: results[ 'network-backend'] = constants.NETWORK_BACKEND_VSWITCH else: raise SettingsNotAvailable("unknown network backend %s" % network_backend) except: pass results['master'] = None try: pt = open(self.join_state_path("etc/xensource/ptoken"), 'r') results['pool-token'] = pt.readline().strip() pt.close() pc = open(self.join_state_path("etc/xensource/pool.conf"), 'r') line = pc.readline().strip() if line.startswith('slave:'): results['master'] = line[6:] pc.close() except: pass finally: self.unmount_state() # read bootloader config to extract various settings try: # Boot device self.mount_boot() boot_config = bootloader.Bootloader.loadExisting( self.boot_fs_mount) # Serial console try: xen_args = boot_config.menu['xe-serial'].getHypervisorArgs() com = [i for i in xen_args if re.match('com[0-9]+=.*', i)] results['serial-console'] = hardware.SerialPort.from_string( com[0]) except Exception: logger.log("Could not parse serial settings") if boot_config.serial: results['serial-console'] = hardware.SerialPort( boot_config.serial['port'], baud=str(boot_config.serial['baud'])) results['bootloader-location'] = boot_config.location if boot_config.default != 'upgrade': results['boot-serial'] = (boot_config.default == 'xe-serial') # Subset of hypervisor arguments xen_args = boot_config.menu[ boot_config.default].getHypervisorArgs() # - cpuid_mask results['host-config']['xen-cpuid-masks'] = filter( lambda x: x.startswith('cpuid_mask'), xen_args) # - dom0_mem dom0_mem_arg = filter(lambda x: x.startswith('dom0_mem'), xen_args) (dom0_mem, dom0_mem_min, dom0_mem_max) = xcp.dom0.parse_mem(dom0_mem_arg[0]) if dom0_mem: results['host-config']['dom0-mem'] = dom0_mem / 1024 / 1024 except: pass self.unmount_boot() return results