Ejemplo n.º 1
0
def process_ibft(ui, interactive):
    """ Bring up any disks that the iBFT should be attached, and reserve the NICs that
    it says should be used for iSCSI
    """
    
    if not have_ibft():
        return

    try: 
        iname, target_configs = read_ibft()
    except:
        # only raise exception if user decides to proceed
        if ui and interactive:
            msg = "Found iSCSI Boot Firmware Table\n\nAttach to disks specified in iBFT?"
            button = ButtonChoiceWindowEx(ui.screen, "Attach iSCSI disks" , msg, ['Yes', 'No'])
            if button == 'no':
                return
        raise
    else:
        # Do nothing if the iBFT contains no valid targets
        if len(target_configs) == 0:
            xelogging.log("process_ibft: No valid target configs found in iBFT")
            return
        
        # If interactive, ask user if he wants to proceed
        if ui and interactive:
            nics = list(set([ conf.iface for conf in target_configs ]))
            nics.sort()
            msg = \
                "Found iSCSI Boot Firmware Table\n\nAttach to disks specified in iBFT?\n\n" \
                "This will reserve %s for iSCSI disk access.  Reserved NICs are not available " \
                "for use as the management interface or for use by virtual machines."  % " and ".join(nics)
            button = ButtonChoiceWindowEx(ui.screen, "Attach iSCSI disks" , msg, ['Yes', 'No'], width=60)
            if button == 'no':
                return
    
    # Bring up the targets
    for conf in target_configs:
        # Bring up interface
        if conf.iface not in ibft_reserved_nics:
            rv = util.runCmd2(['ifconfig', conf.iface, conf.ip, 'netmask', conf.nm])
            assert rv == 0
            ibft_reserved_nics.append(conf.iface)
            xelogging.log("process_ibft: reserving %s for access to iSCSI disk" % conf.iface)
            
        # Pin tgtip to this interface
        if netutil.network(conf.ip, conf.nm) == netutil.network(conf.tgtip, conf.nm):
            rv = util.runCmd2(['ip', 'route', 'add', conf.tgtip, 'dev', conf.iface])
        else:
            assert conf.gw
            rv = util.runCmd2(['ip', 'route', 'add', conf.tgtip, 'dev', conf.iface, 'via', conf.gw])

        # Attach to target (this creates new nodes /dev)
        spec = "iscsi:%s::%d:%d:%s" % (conf.tgtip, conf.port, conf.lun, conf.iqn)
        try:
            disk = attach_rfc4173(iname, spec)
        except Exception as e:
            xelogging.log_exception(e)
            raise RuntimeError, "Could not attach to iSCSI LUN %s" % spec
        xelogging.log("process_ibft: attached iSCSI disk %s." % disk)
Ejemplo n.º 2
0
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, e:
            xelogging.log(
                "A problem occurred whilst scanning for existing installations:"
            )
            xelogging.log_exception(e)
            xelogging.log("This is not fatal.  Continuing anyway.")

        if inst:
            xelogging.log("Found an installation: %s on %s" %
                          (str(inst), disk))
            installs.append(inst)
Ejemplo n.º 3
0
def find_installed_products():
    try:
        installed_products = findXenSourceProducts()
    except Exception, e:
        xelogging.log("A problem occurred whilst scanning for existing installations:")
        xelogging.log_exception(e)
        xelogging.log("This is not fatal.  Continuing anyway.")
        installed_products = []
Ejemplo n.º 4
0
def find_installed_products():
    try:
        installed_products = findXenSourceProducts()
    except Exception, e:
        xelogging.log(
            "A problem occurred whilst scanning for existing installations:")
        xelogging.log_exception(e)
        xelogging.log("This is not fatal.  Continuing anyway.")
        installed_products = []
Ejemplo n.º 5
0
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, state, storage) = diskutil.probeDisk(disk)

        inst = None
        try:
            if boot[0] == diskutil.INSTALL_RETAIL:
                inst = ExistingRetailInstallation(disk, boot[1], state[1], storage)
        except Exception, e:
            xelogging.log("A problem occurred whilst scanning for existing installations:")
            xelogging.log_exception(e)
            xelogging.log("This is not fatal.  Continuing anyway.")

        if inst:
            xelogging.log("Found an installation: %s" % str(inst))
            installs.append(inst)
Ejemplo n.º 6
0
class ExistingInstallation:
    def __init__(self, primary_disk, boot_device, state_device):
        self.primary_disk = primary_disk
        self.boot_device = boot_device
        self.state_device = state_device
        self.state_prefix = ''
        self.settings = None
        self.root_fs = None
        self._boot_fs = None
        self.boot_fs_mount = None

    def __str__(self):
        return "%s %s" % (self.visual_brand, self.visual_version)

    def mount_state(self):
        """ Mount main state partition on self.state_fs. """
        self.state_fs = util.TempMount(
            self.state_device,
            'state-',
        )

    def unmount_state(self):
        self.state_fs.unmount()
        self.state_fs = None

    def join_state_path(self, *path):
        """ Construct an absolute path to a file in the main state partition. """
        return os.path.join(self.state_fs.mount_point, self.state_prefix,
                            *path)

    def getInventoryValue(self, k):
        return self.inventory[k]

    def isUpgradeable(self):
        self.mount_state()
        try:
            # CA-38459: handle missing firstboot directory e.g. Rio
            if not os.path.exists(
                    self.join_state_path('etc/firstboot.d/state')):
                return False
            firstboot_files = [ f for f in os.listdir(self.join_state_path('etc/firstboot.d')) \
                                if f[0].isdigit() and os.stat(self.join_state_path('etc/firstboot.d', f))[stat.ST_MODE] & stat.S_IXUSR ]
            missing_state_files = filter(
                lambda x: not os.path.exists(
                    self.join_state_path('etc/firstboot.d/state', x)),
                firstboot_files)

            result = (len(missing_state_files) == 0)
            if not result:
                xelogging.log('Upgradeability test failed:')
                xelogging.log('  Firstboot:     ' + ', '.join(firstboot_files))
                xelogging.log('  Missing state: ' +
                              ', '.join(missing_state_files))
        finally:
            self.unmount_state()
        return result

    def settingsAvailable(self):
        try:
            self.readSettings()
        except SettingsNotAvailable, text:
            xelogging.log("Settings unavailable: %s" % text)
            return False
        except Exception, e:
            xelogging.log("Settings unavailable: unhandled exception")
            xelogging.log_exception(e)
            return False
Ejemplo n.º 7
0
    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.
                xelogging.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 not results.has_key('manual-hostname'):
                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:
            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:].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 not results.has_key('keymap'):
                xelogging.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')

            networkdb_path = constants.NETWORK_DB
            if not os.path.exists(self.join_state_path(networkdb_path)):
                networkdb_path = constants.OLD_NETWORK_DB
            dbcache_path = constants.DBCACHE
            if not os.path.exists(self.join_state_path(dbcache_path)):
                dbcache_path = constants.OLD_DBCACHE

            if not mgmt_iface:
                xelogging.log('No existing management interface found.')
            elif os.path.exists(self.join_state_path(networkdb_path)):
                networkd_db = constants.NETWORKD_DB
                if not os.path.exists(self.join_state_path(networkd_db)):
                    networkd_db = constants.OLD_NETWORKD_DB
                xelogging.log(
                    'Checking %s for management interface configuration' %
                    networkd_db)

                def fetchIfaceInfoFromNetworkdbAsDict(bridge, iface=None):
                    args = [
                        'chroot', self.state_fs.mount_point, '/' + 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)

            elif os.path.exists(self.join_state_path(dbcache_path)):
                xelogging.log(
                    'Checking %s for management network configuration' %
                    dbcache_path)

                def getText(nodelist):
                    rc = ""
                    for node in nodelist:
                        if node.nodeType == node.TEXT_NODE:
                            rc = rc + node.data
                    return rc.strip().encode()

                xmldoc = xml.dom.minidom.parse(
                    self.join_state_path(dbcache_path))

                pif_uid = None
                for node in xmldoc.documentElement.childNodes:
                    if node.nodeType == node.ELEMENT_NODE and node.tagName == 'network':
                        network = node
                    else:
                        continue
                    # CA-50971: handle renamed networks in MNR
                    if len(network.getElementsByTagName('bridge')) == 0 or \
                       len(network.getElementsByTagName('PIFs')) == 0 or \
                       len(network.getElementsByTagName('PIFs')[0].getElementsByTagName('PIF')) == 0:
                        continue

                    if getText(
                            network.getElementsByTagName('bridge')
                        [0].childNodes) == mgmt_iface:
                        pif_uid = getText(
                            network.getElementsByTagName('PIFs')
                            [0].getElementsByTagName('PIF')[0].childNodes)
                        break
                if pif_uid:
                    for node in xmldoc.documentElement.childNodes:
                        if node.nodeType == node.ELEMENT_NODE and node.tagName == 'pif':
                            pif = node
                        else:
                            continue
                        if pif.getAttribute('ref') == pif_uid:
                            results['net-admin-interface'] = getText(
                                pif.getElementsByTagName('device')
                                [0].childNodes)
                            results['net-admin-bridge'] = mgmt_iface
                            results[
                                'net-admin-configuration'] = NetInterface.loadFromPif(
                                    pif)
                            break
            else:
                xelogging.log(
                    'Checking ifcfg files for management network configuration'
                )
                for cfile in filter(lambda x: True in [x.startswith(y) for y in ['ifcfg-eth', 'ifcfg-bond']], \
                                   os.listdir(self.join_state_path(constants.NET_SCR_DIR))):
                    devcfg = util.readKeyValueFile(self.join_state_path(
                        constants.NET_SCR_DIR, cfile),
                                                   strip_quotes=False)
                    if devcfg.has_key('DEVICE') and devcfg.has_key(
                            'BRIDGE') and devcfg['BRIDGE'] == mgmt_iface:
                        brcfg = util.readKeyValueFile(self.join_state_path(
                            constants.NET_SCR_DIR,
                            'ifcfg-' + devcfg['BRIDGE']),
                                                      strip_quotes=False)
                        results['net-admin-interface'] = devcfg['DEVICE']
                        results['net-admin-bridge'] = devcfg['BRIDGE']

                        # get hardware address if it was recorded, otherwise look it up:
                        if devcfg.has_key('HWADDR'):
                            hwaddr = devcfg['HWADDR']
                        elif devcfg.has_key('MACADDR'):
                            # our bonds have a key called MACADDR instead
                            hwaddr = devcfg['MACADDR']
                        else:
                            hwaddr = netutil.getHWAddr(devcfg['DEVICE'])

                        ifcfg = NetInterface.loadFromIfcfg(
                            self.join_state_path(constants.NET_SCR_DIR,
                                                 'ifcfg-' + devcfg['BRIDGE']))
                        if not ifcfg.hwaddr:
                            ifcfg.hwaddr = hwaddr
                        if ifcfg.isStatic() and not ifcfg.domain and domain:
                            ifcfg.domain = domain
                        results['net-admin-configuration'] = ifcfg
                        break

            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, e:
                    xelogging.log('Scan for driver disks failed:')
                    xelogging.log_exception(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
Ejemplo n.º 8
0
    def _readSettings(self):
        """ Read settings from the installation, returns a results dictionary. """

        results = {}
        if self.version < XENSERVER_5_6_0:
            raise SettingsNotAvailable, "version too old"

        self.mount_state()
        try:

            # timezone:
            tz = None
            clock_file = self.join_state_path("etc/sysconfig/clock")
            if os.path.exists(clock_file):
                fd = open(clock_file, "r")
                lines = fd.readlines()
                fd.close()
                for line in lines:
                    if line.startswith("ZONE="):
                        tz = line[5:].strip()
            if not tz:
                # No timezone found:
                # Supply a default and for interactive installs prompt the user.
                xelogging.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 not results.has_key("manual-hostname"):
                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:
            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:].strip())
            results["ntp-servers"] = ntps

            # keyboard:
            keyboard_file = self.join_state_path("etc/sysconfig/keyboard")
            if os.path.exists(keyboard_file):
                fd = open(keyboard_file, "r")
                lines = fd.readlines()
                fd.close()
                for line in lines:
                    if line.startswith("KEYTABLE="):
                        results["keymap"] = line[9:].strip()
            # 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 not results.has_key("keymap"):
                xelogging.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 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 os.path.exists(self.join_state_path(constants.DBCACHE)):

                def getText(nodelist):
                    rc = ""
                    for node in nodelist:
                        if node.nodeType == node.TEXT_NODE:
                            rc = rc + node.data
                    return rc.strip().encode()

                xmldoc = xml.dom.minidom.parse(self.join_state_path(constants.DBCACHE))

                pif_uid = None
                for node in xmldoc.documentElement.childNodes:
                    if node.nodeType == node.ELEMENT_NODE and node.tagName == "network":
                        network = node
                    else:
                        continue
                    # CA-50971: handle renamed networks in MNR
                    if (
                        len(network.getElementsByTagName("bridge")) == 0
                        or len(network.getElementsByTagName("PIFs")) == 0
                        or len(network.getElementsByTagName("PIFs")[0].getElementsByTagName("PIF")) == 0
                    ):
                        continue

                    if getText(network.getElementsByTagName("bridge")[0].childNodes) == mgmt_iface:
                        pif_uid = getText(
                            network.getElementsByTagName("PIFs")[0].getElementsByTagName("PIF")[0].childNodes
                        )
                        break
                if pif_uid:
                    for node in xmldoc.documentElement.childNodes:
                        if node.nodeType == node.ELEMENT_NODE and node.tagName == "pif":
                            pif = node
                        else:
                            continue
                        if pif.getAttribute("ref") == pif_uid:
                            results["net-admin-interface"] = getText(pif.getElementsByTagName("device")[0].childNodes)
                            results["net-admin-bridge"] = mgmt_iface
                            results["net-admin-configuration"] = NetInterface.loadFromPif(pif)
                            break
            else:
                for cfile in filter(
                    lambda x: True in [x.startswith(y) for y in ["ifcfg-eth", "ifcfg-bond"]],
                    os.listdir(self.join_state_path(constants.NET_SCR_DIR)),
                ):
                    devcfg = util.readKeyValueFile(
                        self.join_state_path(constants.NET_SCR_DIR, cfile), strip_quotes=False
                    )
                    if devcfg.has_key("DEVICE") and devcfg.has_key("BRIDGE") and devcfg["BRIDGE"] == mgmt_iface:
                        brcfg = util.readKeyValueFile(
                            self.join_state_path(constants.NET_SCR_DIR, "ifcfg-" + devcfg["BRIDGE"]), strip_quotes=False
                        )
                        results["net-admin-interface"] = devcfg["DEVICE"]
                        results["net-admin-bridge"] = devcfg["BRIDGE"]

                        # get hardware address if it was recorded, otherwise look it up:
                        if devcfg.has_key("HWADDR"):
                            hwaddr = devcfg["HWADDR"]
                        elif devcfg.has_key("MACADDR"):
                            # our bonds have a key called MACADDR instead
                            hwaddr = devcfg["MACADDR"]
                        else:
                            # XXX what if it's been renamed out of existence?
                            try:
                                hwaddr = netutil.getHWAddr(devcfg["DEVICE"])
                            except:
                                hwaddr = None

                        ifcfg = NetInterface.loadFromIfcfg(
                            self.join_state_path(constants.NET_SCR_DIR, "ifcfg-" + devcfg["BRIDGE"])
                        )
                        if not ifcfg.hwaddr:
                            ifcfg.hwaddr = hwaddr
                        if ifcfg.isStatic() and not ifcfg.domain and domain:
                            ifcfg.domain = domain
                        results["net-admin-configuration"] = ifcfg
                        break

            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.Repository(
                                repository.FilesystemAccessor(
                                    self.join_state_path(constants.INSTALLED_REPOS_DIR, repo_id)
                                )
                            )
                            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.Repository.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, e:
                    xelogging.log("Scan for driver disks failed:")
                    xelogging.log_exception(e)

            results["repo-list"] = repo_list

            results["ha-armed"] = False
            try:
                db = open(self.join_state_path("var/xapi/local.db"), "r")
                if db.readline().find('<row key="ha.armed" value="true"') != -1:
                    results["ha-armed"] = True
                db.close()
            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