Пример #1
0
    def loadFromIfcfg(filename):
        def valOrNone(d, k):
            return d.has_key(k) and d[k] or None

        conf = util.readKeyValueFile(filename)
        mode = None
        if conf.has_key('BOOTPROTO'):
            if conf['BOOTPROTO'] == 'static' or conf.has_key('IPADDR'):
                mode = NetInterface.Static
            elif conf['BOOTPROTO'] == 'dhcp':
                mode = NetInterface.DHCP

        hwaddr = valOrNone(conf, 'HWADDR')
        if not hwaddr:
            hwaddr = valOrNone(conf, 'MACADDR')
        if not hwaddr:
            try:
                hwaddr = netutil.getHWAddr(conf['DEVICE'])
            except:
                pass
        dns = None
        n = 1
        while conf.has_key('DNS%d' % n):
            if not dns: dns = []
            dns.append(conf['DNS%d' % n])
            n += 1

        return NetInterface(mode, hwaddr, valOrNone(conf, 'IPADDR'), valOrNone(conf, 'NETMASK'),
                            valOrNone(conf, 'GATEWAY'), dns, valOrNone(conf, 'DOMAIN'))
Пример #2
0
    def loadFromIfcfg(filename):
        def valOrNone(d, k):
            return k in d and d[k] or None

        conf = util.readKeyValueFile(filename)
        mode = None
        if 'BOOTPROTO' in conf:
            if conf['BOOTPROTO'] == 'static' or 'IPADDR' in conf:
                mode = NetInterface.Static
            elif conf['BOOTPROTO'] == 'dhcp':
                mode = NetInterface.DHCP

        hwaddr = valOrNone(conf, 'HWADDR')
        if not hwaddr:
            hwaddr = valOrNone(conf, 'MACADDR')
        if not hwaddr:
            hwaddr = netutil.getHWAddr(conf['DEVICE'])
        dns = None
        n = 1
        while 'DNS%d' % n in conf:
            if not dns: dns = []
            dns.append(conf['DNS%d' % n])
            n += 1

        modev6 = None
        if 'DHCPV6C' in conf:
            modev6 = NetInterface.DHCP
        elif 'IPV6_AUTOCONF' in conf:
            modev6 = NetInterface.Autoconf
        elif 'IPV6INIT' in conf:
            modev6 = NetInterface.Static

        ni = NetInterface(mode, hwaddr, valOrNone(conf, 'IPADDR'),
                          valOrNone(conf, 'NETMASK'),
                          valOrNone(conf, 'GATEWAY'), dns,
                          valOrNone(conf, 'DOMAIN'))
        ni.addIPv6(modev6, valOrNone(conf, 'IPV6ADDR'),
                   valOrNone(conf, 'IPV6_DEFAULTGW'))
        return ni
Пример #3
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
Пример #4
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.
                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
Пример #5
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