Ejemplo n.º 1
0
class BaseKitInstaller(KitInstallerBase):
    puppet_modules = ['univa-tortuga_kit_base']

    def __init__(self):
        self._global_param_db_api = GlobalParameterDbApi()
        super().__init__()

    def get_db_parameter_value(self, key, default='__throw_exception__'):
        try:
            return self._global_param_db_api.getParameter(key).getValue()
        except ParameterNotFound:
            if default == '__throw_exception__':
                raise
        return default

    def get_db_parameter_bool(self, key, default='__throw_exception__'):
        value = self.get_db_parameter_value(key, default)
        return bool(value[0] == '1')

    def set_db_parameter_value(self, key, value):
        self._global_param_db_api.addParameter(Parameter(name=key,
                                                         value=value))

    def action_post_install(self):
        super().action_post_install()
        return PostInstallAction(self)()
Ejemplo n.º 2
0
class ParameterManager(TortugaObjectManager, Singleton):
    def __init__(self):
        super(ParameterManager, self).__init__()

        self._globalParameterDbApi = GlobalParameterDbApi()

    def getParameter(self, name):
        """
        Raises:
            ParameterNotFound
        """

        return self._globalParameterDbApi.getParameter(name)

    def getBoolParameter(self, name, default=None):
        """
        Raises:
            ParameterNotFound
            TortugaException
        """

        try:
            param = self.getParameter(name)
        except ParameterNotFound:
            if default is not None:
                return default

            raise

        return param.getValue() and \
            param.getValue()[0].lower() in ('1', 'y', 't')

    def getIntParameter(self, name, default=None):
        """
        Raises:
            ParameterNotFound
            TortugaException
        """

        try:
            param = self.getParameter(name)
        except ParameterNotFound:
            if default is not None:
                return default

            raise

        return int(param.getValue())

    def getParameterList(self):
        return self._globalParameterDbApi.getParameterList()

    def upsertParameter(self, parameter):
        return self._globalParameterDbApi.upsertParameter(parameter)

    def deleteParameter(self, name):
        return self._globalParameterDbApi.deleteParameter(name)
Ejemplo n.º 3
0
    def configure(self):
        fp = open(CONFIG_FILE, 'w')

        session = self.session

        try:
            print("# ", file=fp)
            print("# Dynamically generated by: genconfig (Do not edit!)",
                  file=fp)
            print("#", file=fp)
            print("", file=fp)

            try:
                result = GlobalParameterDbApi().getParameter(
                    self.session, 'DNSZone'
                )

                dnszone = result.getValue()
            except ParameterNotFound:
                dnszone = ''

            for db_nic in session.query(Nic).order_by(Nic.ip).all():
                if db_nic.node.state == 'Deleted':
                    continue

                if not db_nic.ip:
                    continue

                name = db_nic.node.name.split('.')[0]

                print('Host {}'.format(db_nic.ip), file=fp)
                print('\tStrictHostKeyChecking no', file=fp)

                print('Host {}.{}'.format(name, dnszone), file=fp)
                print('\tStrictHostKeyChecking no', file=fp)

                print('Host {}'.format(name), file=fp)
                print('\tStrictHostKeyChecking no', file=fp)

                print("", file=fp)

            print('Host *', file=fp)
            print('\t# ssh_config defaults', file=fp)
            print('\tGSSAPIAuthentication yes', file=fp)
            print('\tForwardX11Trusted yes', file=fp)
            print('\t# tortuga defaults', file=fp)
            print('\tNoHostAuthenticationForLocalhost yes', file=fp)
            print('\tStrictHostKeyChecking no', file=fp)

        finally:
            fp.close()
Ejemplo n.º 4
0
    def __init__(self, osFamilyInfo):
        super(OSSupport, self).__init__(osFamilyInfo)

        self._cm = ConfigManager()
        self._globalParameterDbApi = GlobalParameterDbApi()

        try:
            depot_dir = \
                self._globalParameterDbApi.getParameter('depot').getValue()
        except ParameterNotFound:
            # Fallback to legacy default
            depot_dir = '/depot'

        self._cm.setDepotDir(depot_dir)
Ejemplo n.º 5
0
 def __init__(self):
     super(SoftwareProfileManager, self).__init__()
     self._sp_db_api = SoftwareProfileDbApi()
     self._node_db_api = NodeDbApi()
     self._component_db_api = ComponentDbApi()
     self._global_param_db_api = GlobalParameterDbApi()
     self._kit_db_api = KitDbApi()
     self._config_manager = ConfigManager()
Ejemplo n.º 6
0
    def __init__(self):
        super(HardwareProfileManager, self).__init__()

        self._hpDbApi = HardwareProfileDbApi()
        self._spDbApi = SoftwareProfileDbApi()
        self._networkDbApi = NetworkDbApi()
        self._globalParameterDbApi = GlobalParameterDbApi()
        self._nodeDbApi = NodeDbApi()
Ejemplo n.º 7
0
 def __init__(self):
     super(SoftwareProfileManager, self).__init__()
     self._sp_db_api = SoftwareProfileDbApi()
     self._node_db_api = NodeDbApi()
     self._component_db_api = ComponentDbApi()
     self._global_param_db_api = GlobalParameterDbApi()
     self._kit_db_api = KitDbApi()
     self._config_manager = ConfigManager()
     self._logger = logging.getLogger(SOFTWARE_PROFILE_NAMESPACE)
Ejemplo n.º 8
0
    def __init__(self):
        super(HardwareProfileManager, self).__init__()

        self._hpDbApi = HardwareProfileDbApi()
        self._spDbApi = SoftwareProfileDbApi()
        self._networkDbApi = NetworkDbApi()
        self._globalParameterDbApi = GlobalParameterDbApi()
        self._nodeDbApi = NodeDbApi()
        self._logger = logging.getLogger(HARDWARE_PROFILE_NAMESPACE)
Ejemplo n.º 9
0
    def _get_global_parameter(key, default=None):
        """
        Get parameter from the DB.

        :param key: String
        :param default: String
        :returns: DbObject
        """
        try:
            return GlobalParameterDbApi().getParameter(key).getValue()
        except ParameterNotFound:
            return default
Ejemplo n.º 10
0
    def action_configure(self, _, *args, **kwargs):
        """
        Configure.

        :param _: Unused
        :param *args: Unused
        :param **kwargs: Unused
        :returns: None
        """

        try:
            result = GlobalParameterDbApi().getParameter(
                self.session,
                'DHCPLeaseTime'
            )

            dhcp_lease_time = int(result.getValue())
        except ParameterNotFound:
            dhcp_lease_time = 2400

        try:
            result = GlobalParameterDbApi().getParameter(
                self.session,
                'DNSZone')

            dns_zone = result.getValue()
        except ParameterNotFound:
            dns_zone = ''

        installer_node = NodeApi().getInstallerNode(self.session)

        self._manager.configure(
            dhcp_lease_time,
            dns_zone,
            self._get_provisioning_nics_ip(installer_node),
            self._dhcp_subnets(),
            installerNode=installer_node,
            bUpdateSysconfig=kwargs.get('bUpdateSysconfig', True),
            kit_settings=self._get_kit_settings_dictionary
        )
Ejemplo n.º 11
0
    def __init__(self):
        TortugaDbApi.__init__(self)

        self._nodesDbHandler = NodesDbHandler()
        self._globalParameterDbApi = GlobalParameterDbApi()
Ejemplo n.º 12
0
class NodeDbApi(TortugaDbApi):
    """
    Nodes DB API class.
    """
    def __init__(self):
        TortugaDbApi.__init__(self)

        self._nodesDbHandler = NodesDbHandler()
        self._globalParameterDbApi = GlobalParameterDbApi()

    def getNode(self,
                name: str,
                optionDict: Optional[Union[dict, None]] = None):
        """
        Get node from the db.

            Returns:
                node
            Throws:
                NodeNotFound
                DbError
        """

        session = DbManager().openSession()

        try:
            dbNode = self._nodesDbHandler.getNode(session, name)

            self.loadRelations(dbNode, optionDict)

            self.loadRelations(dbNode, {
                'softwareprofile': True,
                'hardwareprofile': True,
                'tags': True,
            })

            return Node.getFromDbDict(dbNode.__dict__)
        except TortugaException as ex:
            raise
        except Exception as ex:
            self.getLogger().exception('%s' % ex)
            raise
        finally:
            DbManager().closeSession()

    def getNodesByAddHostSession(self, ahSession):
        """
        Get node(s) from db based their addhost session
        """

        session = DbManager().openSession()

        try:
            return self.__convert_nodes_to_TortugaObjectList(
                self._nodesDbHandler.getNodesByAddHostSession(
                    session, ahSession))
        except TortugaException as ex:
            raise
        except Exception as ex:
            self.getLogger().exception('%s' % ex)
            raise
        finally:
            DbManager().closeSession()

    def getNodesByNameFilter(self, _filter):
        """
        Get node(s) from db based on the name filter
        """

        session = DbManager().openSession()

        try:
            dbNodes = self._nodesDbHandler.getNodesByNameFilter(
                session, _filter)

            return self.getTortugaObjectList(Node, dbNodes)
        except TortugaException as ex:
            raise
        except Exception as ex:
            self.getLogger().exception('%s' % ex)
            raise
        finally:
            DbManager().closeSession()

    def getNodeById(self,
                    nodeId: int,
                    optionDict: Optional[Union[dict, None]] = None):

        session = DbManager().openSession()

        try:
            dbNode = self._nodesDbHandler.getNodeById(session, nodeId)

            self.loadRelations(dbNode, optionDict)

            return Node.getFromDbDict(dbNode.__dict__)
        except TortugaException as ex:
            raise
        except Exception as ex:
            self.getLogger().exception('%s' % ex)
            raise
        finally:
            DbManager().closeSession()

    def getNodeByIp(self, ip):
        session = DbManager().openSession()

        try:
            node = self._nodesDbHandler.getNodeByIp(session, ip)

            return Node.getFromDbDict(node.__dict__)
        except TortugaException as ex:
            raise
        except Exception as ex:
            self.getLogger().exception('%s' % ex)
            raise
        finally:
            DbManager().closeSession()

    def __convert_nodes_to_TortugaObjectList(
            self,
            nodes,
            relations: Optional[Union[dict,
                                      None]] = None) -> TortugaObjectList:
        nodeList = TortugaObjectList()

        relations = relations or dict(softwareprofile=True,
                                      hardwareprofile=True)

        for t in nodes:
            self.loadRelations(t, relations)

            # Always load 'tags' relation
            self.loadRelations(t, {'tags': True})

            node = Node.getFromDbDict(t.__dict__)

            nodeList.append(node)

        return nodeList

    def getNodeList(self, tags=None):
        """
        Get list of all available nodes from the db.

            Returns:
                [node]
            Throws:
                DbError
        """

        session = DbManager().openSession()

        try:
            return self.__convert_nodes_to_TortugaObjectList(
                self._nodesDbHandler.getNodeList(session, tags=tags))
        except TortugaException as ex:
            raise
        except Exception as ex:
            self.getLogger().exception('%s' % ex)
            raise
        finally:
            DbManager().closeSession()

    def getProvisioningInfo(self, nodeName):
        """
        Get the provisioing information for a given provisioned address

            Returns:
                [provisioningInformation structure]
            Throws:
                NodeNotFound
                DbError
        """

        session = DbManager().openSession()

        try:
            provisioningInfo = ProvisioningInfo()

            dbNode = self._nodesDbHandler.getNode(session, nodeName)

            if dbNode.softwareprofile:
                self.loadRelations(dbNode.softwareprofile, {
                    'partitions': True,
                    'packages': True,
                })

                for component in dbNode.softwareprofile.components:
                    self.loadRelations(
                        component, {
                            'kit': True,
                            'os': True,
                            'family': True,
                            'os_components': True,
                            'osfamily_components': True,
                        })

            self.loadRelation(dbNode, 'hardwareprofile')

            provisioningInfo.setNode(Node.getFromDbDict(dbNode.__dict__))

            globalParameters = self._globalParameterDbApi.getParameterList()

            # TODO: this is a terrible hack until something better comes
            # along.

            p = Parameter()
            p.setName('Installer')

            hostName = socket.gethostname().split('.', 1)[0]

            if '.' in dbNode.name:
                nodeDomain = dbNode.name.split('.', 1)[1]

                priInstaller = hostName + '.%s' % (nodeDomain)
            else:
                priInstaller = hostName

            p.setValue(priInstaller)

            globalParameters.append(p)

            provisioningInfo.setGlobalParameters(globalParameters)

            return provisioningInfo
        except TortugaException as ex:
            raise
        except Exception as ex:
            self.getLogger().exception('%s' % ex)
            raise
        finally:
            DbManager().closeSession()

    def startupNode(self, nodespec, remainingNodeList=None, bootMethod='n'):
        """
        Start Node
        """

        session = DbManager().openSession()

        try:
            dbNodes = self.__expand_nodespec(session, nodespec)

            if not dbNodes:
                raise NodeNotFound('No matching nodes for nodespec [%s]' %
                                   (nodespec))

            self._nodesDbHandler.startupNode(
                session,
                dbNodes,
                remainingNodeList=remainingNodeList or [],
                bootMethod=bootMethod)

            session.commit()
        except TortugaException as ex:
            session.rollback()
            raise
        except Exception as ex:
            session.rollback()
            self.getLogger().exception('%s' % ex)
            raise
        finally:
            DbManager().closeSession()

    def shutdownNode(self, nodespec, bSoftShutdown=False):
        """
        Shutdown Node

        Raises:
            NodeNotFound
        """

        session = DbManager().openSession()

        try:
            dbNodes = self.__expand_nodespec(session, nodespec)

            if not dbNodes:
                raise NodeNotFound('No matching nodes for nodespec [%s]' %
                                   (nodespec))

            self._nodesDbHandler.shutdownNode(session, dbNodes, bSoftShutdown)

            session.commit()
        except TortugaException as ex:
            session.rollback()
            raise
        except Exception as ex:
            session.rollback()
            self.getLogger().exception('%s' % ex)
            raise
        finally:
            DbManager().closeSession()

    def __expand_nodespec(self, session, nodespec):
        # Expand wildcards in nodespec. Each token in the nodespec can
        # be wildcard that expands into one or more nodes.

        filter_spec = []

        for nodespec_token in nodespec.split(','):
            # Convert shell-style wildcards into SQL wildcards
            if '*' in nodespec_token or '?' in nodespec_token:
                filter_spec.append(
                    nodespec_token.replace('*', '%').replace('?', '_'))

                continue

            # Add nodespec "AS IS"
            filter_spec.append(nodespec_token)

        return self._nodesDbHandler.getNodesByNameFilter(session, filter_spec)

    def evacuateChildren(self, nodeName):
        """
        Evacuate Children of node
        """

        session = DbManager().openSession()

        try:
            dbNode = self._nodesDbHandler.getNode(session, nodeName)

            self._nodesDbHandler.evacuateChildren(session, dbNode)

            session.commit()
        except TortugaException as ex:
            session.rollback()
            raise
        except Exception as ex:
            session.rollback()
            self.getLogger().exception('%s' % ex)
            raise
        finally:
            DbManager().closeSession()

    def getChildrenList(self, nodeName):
        """
        Get children of node

        Raises:
            NodeNotFound
        """

        session = DbManager().openSession()

        try:
            dbNode = self._nodesDbHandler.getNode(session, nodeName)

            return self.getTortugaObjectList(Node, dbNode.children)
        except TortugaException as ex:
            raise
        except Exception as ex:
            self.getLogger().exception('%s' % ex)
            raise
        finally:
            DbManager().closeSession()

    def checkpointNode(self, nodeName):
        """
        Checkpoint Node
        """

        session = DbManager().openSession()

        try:
            self._nodesDbHandler.checkpointNode(session, nodeName)
            session.commit()
        except TortugaException as ex:
            session.rollback()
            raise
        except Exception as ex:
            session.rollback()
            self.getLogger().exception('%s' % ex)
            raise
        finally:
            DbManager().closeSession()

    def revertNodeToCheckpoint(self, nodeName):
        """
        Revert Node to Checkpoint
        """

        session = DbManager().openSession()

        try:
            self._nodesDbHandler.revertNodeToCheckpoint(session, nodeName)

            session.commit()
        except TortugaException as ex:
            session.rollback()
            raise
        except Exception as ex:
            session.rollback()
            self.getLogger().exception('%s' % ex)
            raise
        finally:
            DbManager().closeSession()

    def migrateNode(self, nodeName, remainingNodeList, liveMigrate):
        """
        Migrate Node
        """

        session = DbManager().openSession()

        try:
            self._nodesDbHandler.migrateNode(session, nodeName,
                                             remainingNodeList, liveMigrate)

            session.commit()
        except TortugaException as ex:
            session.rollback()
            raise
        except Exception as ex:
            session.rollback()
            self.getLogger().exception('%s' % ex)
            raise
        finally:
            DbManager().closeSession()

    def setParentNode(self, nodeName, parentNodeName):
        '''
        Raises:
            NodeNotFound
        '''

        session = DbManager().openSession()

        try:
            dbNode = self._nodesDbHandler.getNode(session, nodeName)

            # Setting the parent to 'None' is equivalent to unsetting it
            dbNode.parentnode = self._nodesDbHandler.getNode(
                session, parentNodeName) if parentNodeName else None

            session.commit()
        except TortugaException as ex:
            session.rollback()
            raise
        except Exception as ex:
            session.rollback()
            self.getLogger().exception('%s' % ex)
            raise
        finally:
            DbManager().closeSession()

    def getNodesByNodeState(self, state):
        session = DbManager().openSession()

        try:
            return self.getTortugaObjectList(
                Node, self._nodesDbHandler.getNodesByNodeState(session, state))
        except TortugaException as ex:
            raise
        except Exception as ex:
            self.getLogger().exception('%s' % (ex))
            raise
        finally:
            DbManager().closeSession()
Ejemplo n.º 13
0
    def __init__(self):
        super(ParameterManager, self).__init__()

        self._globalParameterDbApi = GlobalParameterDbApi()
Ejemplo n.º 14
0
 def __init__(self):
     self._global_param_db_api = GlobalParameterDbApi()
     super().__init__()
Ejemplo n.º 15
0
class OSSupport(OsSupportBase):
    def __init__(self, osFamilyInfo):
        super(OSSupport, self).__init__(osFamilyInfo)

        self._cm = ConfigManager()
        self._globalParameterDbApi = GlobalParameterDbApi()

        try:
            depot_dir = \
                self._globalParameterDbApi.getParameter('depot').getValue()
        except ParameterNotFound:
            # Fallback to legacy default
            depot_dir = '/depot'

        self._cm.setDepotDir(depot_dir)

    def getPXEReinstallSnippet(self, ksurl, node, hardwareprofile=None,
                               softwareprofile=None): \
            # pylint: disable=no-self-use
        # General kickstart/kernel parameters

        # Find the first nic marked as bootable
        nics = [nic for nic in node.nics if nic.boot]

        if not nics:
            raise NicNotFound(
                'Node [%s] does not have a bootable NIC' % (node.name))

        # Choose the first one
        nic = nics[0]

        if hardwareprofile is None:
            hardwareprofile = node.hardwareprofile

        if softwareprofile is None:
            softwareprofile = node.softwareprofile

        # Use settings from software profile, if defined, otherwise use
        # settings from hardware profile.
        bootParams = getBootParameters(hardwareprofile, softwareprofile)

        kernel = bootParams['kernel']
        kernelParams = bootParams['kernelParams']
        initrd = bootParams['initrd']

        bootargs = [
        ]

        if softwareprofile.os.family.version == '7':
            # RHEL 7.x
            bootargs.append('inst.ks=%s' % (ksurl))
        else:
            # RHEL 5.x and 6.x
            bootargs.append('ks=%s' % (ksurl))

            bootargs.append('ksdevice=%s' % (nic.networkdevice.name))

        # Append kernel parameters, if defined.
        if kernelParams:
            bootargs.append(kernelParams)

        result = '''\
    kernel %s
    append initrd=%s %s''' % (kernel, initrd, ' '.join(bootargs))

        return result

    def __get_kickstart_network_entry(self, dbNode, hardwareprofile, nic): \
            # pylint: disable=no-self-use
        bProvisioningNic = nic.network == hardwareprofile.nics[0].network

        installer_private_ip = hardwareprofile.nics[0].ip

        if not bProvisioningNic and not nic.network.usingDhcp and not nic.ip:
            # Unconfigured public static IP network
            return None

        bActivate = False

        # By default, all interfaces are enabled at on boot
        bOnBoot = True

        # Use the network device name, as specified in the hardware profile
        netargs = [
            'network --device %s' % (nic.networkdevice.name)
        ]

        if bProvisioningNic:
            netargs.append(
                '--bootproto %s' % (
                    'static' if bProvisioningNic or
                    not nic.network.usingDhcp else 'dhcp'))

            netargs.append('--ip=%s' % (nic.ip))
            netargs.append('--netmask=%s' % (nic.network.netmask))
            netargs.append('--nameserver=%s' % (installer_private_ip))

            bActivate = True
        else:
            if nic.network and nic.network.usingDhcp:
                netargs.append('--bootproto dhcp')
            else:
                netargs.append('--bootproto static')

                if nic.ip:
                    netargs.append('--ip=%s' % (nic.ip))
                    netargs.append('--netmask=%s' % (nic.network.netmask))
                else:
                    # Do not enable interface if it's not configured
                    netargs.append('--onboot=no')

                    bOnBoot = False

        # Store provisioning network interface device name for
        # later reference in the template

        # Ensure all interfaces are activated
        if bActivate:
            netargs.append('--activate')

        bDefaultRoute = True

        if bProvisioningNic:
            # This is the nic connected to the provisioning network.

            if len(dbNode.nics) > 1:
                # Disable the default route on the management network.
                netargs.append('--nodefroute')

                bDefaultRoute = False
        else:
            # Disable DNS for all interfaces other than the
            # provisioning network
            if bOnBoot:
                netargs.append('--nodns')

        if nic.network.gateway and bDefaultRoute:
            netargs.append('--gateway %s' % (nic.network.gateway))

        return ' '.join(netargs)

    def __validate_node(self, node): \
            # pylint: disable=no-self-use
        """
        Raises:
            NodeNotFound
            NicNotFound
        """

        if not node.name:
            raise NodeNotFound('Node must have a name')

        if not node.nics:
            raise NicNotFound('Node [%s] has no associated nics' % (
                node.name))

    def __kickstart_get_timezone(self):
        tz = self._globalParameterDbApi.getParameter(
            'Timezone_zone').getValue()

        # Ensure timezone does not contain any spaces
        return tz.replace(' ', '_')

    def __kickstart_get_network_section(self, node, hardwareprofile):
        # Ensure nics are processed in order (ie. eth0, eth1, eth2...)
        nics = node.nics
        nics.sort(key=lambda nic: nic.networkdevice.name)

        network_entries = []
        hostname_set = False

        # Iterate over nics, adding 'network' Kickstart entries for each
        for nic in nics:
            networkString = self.__get_kickstart_network_entry(
                node, hardwareprofile, nic)

            if not networkString:
                continue

            if not hostname_set and nic.boot and \
                    nic.network.type == 'provision':
                networkString += ' --hostname=%s' % (node.name)

                hostname_set = True

            network_entries.append(networkString)

        return '\n'.join(network_entries)

    def __kickstart_get_repos(self, dbSwProfile, installer_private_ip):
        repo_entries = []

        for dbComponent in dbSwProfile.components:
            dbKit = dbComponent.kit
            if dbKit.isOs or dbKit.name != 'base':
                # Do not add repos for OS kits
                continue

            kitVer = '%s-%s' % (dbKit.version, dbKit.iteration)
            kitArch = 'noarch'

            subpath = '%s/%s/%s' % (dbKit.name, kitVer, kitArch)

            # Check if repository actually exists
            if not os.path.exists(os.path.join(self._cm.getDepotDir(),
                                               'kits',
                                               subpath,
                                               'repodata',
                                               'repomd.xml')):
                # Repository for specified kit is empty. Nothing to do...
                continue

            url = self._cm.getYumRootUrl(installer_private_ip) + \
                '/' + subpath

            repo_entries.append(
                'repo --name %s --baseurl=%s' % (dbKit.name, url))

        subpath = '3rdparty/%s/%s/%s' % (dbSwProfile.os.family.name,
                                         dbSwProfile.os.family.version,
                                         dbSwProfile.os.arch)

        if os.path.exists(os.path.join(self._cm.getRoot(),
                                       'repos',
                                       subpath,
                                       'repodata/repomd.xml')):
            # Third-party repository contains packages, include it in
            # Kickstart
            url = '%s/%s' % (
                self._cm.getYumRootUrl(installer_private_ip), subpath)

            repo_entries.append(
                'repo --name tortuga-third-party --baseurl=%s' % (url))

        return repo_entries

    def __get_kickstart_template(self, swprofile):
        ksTemplate = os.path.join(
            self._cm.getKitConfigBase(),
            'kickstart-%s.tmpl' % (swprofile.os.family.name.encode('ascii')))

        if not os.path.exists(ksTemplate):
            ksTemplate = os.path.join(
                self._cm.getKitConfigBase(),
                'kickstart-%s.tmpl' % (swprofile.name.encode('ascii')))

            if not os.path.exists(ksTemplate):
                ksTemplate = os.path.join(
                    self._cm.getKitConfigBase(), 'kickstart.tmpl')

        return ksTemplate

    def __kickstart_get_partition_section(self, softwareprofile):
        buf = """\
#!/bin/sh
# Determine how many drives we have
"""

        # Temporary workaround for RHEL 5.7 based distros
        # https://bugzilla.redhat.com/show_bug.cgi?format=multiple&id=709880
        if softwareprofile.os.version == '5.7':
            buf += 'set $(PYTHONPATH=/usr/lib/booty list-harddrives)\n'
        else:
            buf += 'set $(list-harddrives)\n'

        buf += """
d1=$1
d2=$3
d3=$5
d4=$7
"""

        clearpartstr = '''
cat >/tmp/partinfo << __PARTINFO__
zerombr
'''

        disksToPreserve = []

        # Need to get the drives to clear
        clearpartstr += 'clearpart '
        driveNumbers = []

        for dbPartition in softwareprofile.partitions:
            disk = dbPartition.device.split('.')[0]

            if disk not in driveNumbers:
                driveNumbers.append(disk)

                if not dbPartition.preserve:
                    # This is a partition to clear
                    if len(driveNumbers) == 1:
                        # First drive
                        clearpartstr += ('--all --initlabel'
                                         ' --drives="${d%s:-nodisk}' % (
                                             disk))
                    else:
                        clearpartstr += ',${d%s:-nodisk}' % (disk)
                else:
                    disksToPreserve.append(disk)

        clearpartstr += "--none" if not driveNumbers else '"'
        clearpartstr += '\n'

        for diskNum in driveNumbers:
            if diskNum in disksToPreserve:
                continue

            buf += '''
dd if=/dev/zero of=$d%s bs=512 count=1
''' % (diskNum)

        buf += clearpartstr

        bootloaderLocation = "mbr"

        # Now create partitions
        for dbPartition in softwareprofile.partitions:
            if dbPartition.bootLoader:
                # Can't control the partition in anaconda...it will be on
                # the drive with the boot partition
                bootloaderLocation = 'partition'

            buf += self._processPartition(dbPartition)

        # now do the bootloader
        buf += (
            'bootloader --location=%s --driveorder=${d1:-nodisk}\n' % (
                bootloaderLocation))

        buf += '__PARTINFO__\n'

        return buf

    def __get_template_subst_dict(self, node, hardwareprofile,
                                  softwareprofile):
        hardwareprofile = hardwareprofile \
            if hardwareprofile else node.hardwareprofile
        softwareprofile = softwareprofile \
            if softwareprofile else node.softwareprofile

        installer_public_fqdn = socket.getfqdn()
        installer_hostname = installer_public_fqdn.split('.')[0]

        installer_private_ip = hardwareprofile.nics[0].ip

        try:
            private_domain = self._globalParameterDbApi.\
                getParameter('DNSZone').getValue()
        except ParameterNotFound:
            private_domain = None

        installer_private_fqdn = '%s%s%s' % (
            installer_hostname,
            get_installer_hostname_suffix(
                hardwareprofile.nics[0], enable_interface_aliases=None),
            '.%s' % (private_domain) if private_domain else '')

        vals = node.name.split('.', 1)
        domain = vals[1].lower() if len(vals) == 2 else ''

        d = {
            'fqdn': node.name,
            'domain': domain,
            'hostname': installer_hostname,
            'installer_private_fqdn': installer_private_fqdn,
            'installer_private_domain': private_domain,
            'installer_private_ip': installer_private_ip,
            'puppet_master_fqdn': installer_public_fqdn,
            'installer_public_fqdn': installer_public_fqdn,
            'ntpserver': installer_private_ip,
            'os': softwareprofile.os.name,
            'osfamily': softwareprofile.os.family.name,
            'osfamilyvers': int(softwareprofile.os.family.version),
            # These are deprecated and included for backwards compatibility
            # only. Do not reference them in any new kickstart templates.
            'primaryinstaller': installer_private_fqdn,
            'puppetserver': installer_public_fqdn,
            'installerip': installer_private_ip,
        }

        # Add entry for install package source
        d['url'] = '%s/%s/%s/%s' % (
            self._cm.getYumRootUrl(installer_private_fqdn),
            softwareprofile.os.name,
            softwareprofile.os.version,
            softwareprofile.os.arch)

        d['lang'] = 'en_US.UTF-8'

        d['keyboard'] = 'us'

        d['networkcfg'] = self.__kickstart_get_network_section(
            node, hardwareprofile)

        d['rootpw'] = self._generatePassword()

        d['timezone'] = self.__kickstart_get_timezone()

        d['includes'] = '%include /tmp/partinfo'

        d['repos'] = '\n'.join(
            self.__kickstart_get_repos(
                softwareprofile, installer_private_fqdn))

        # Retain this for backwards compatibility with legacy Kickstart
        # templates
        d['packages'] = '\n'.join([])

        d['prescript'] = self.__kickstart_get_partition_section(
            softwareprofile)

        d['installer_url'] = self._cm.getInstallerUrl(installer_private_fqdn)

        d['cfmstring'] = self._cm.getCfmPassword()

        return d

    def getKickstartFileContents(self, node, hardwareprofile,
                                 softwareprofile):
        # Perform basic sanity checking before proceeding
        self.__validate_node(node)

        template_subst_dict = self.__get_template_subst_dict(
            node, hardwareprofile, softwareprofile)

        with open(self.__get_kickstart_template(softwareprofile)) as fp:
            tmpl = fp.read()

        return Template(tmpl).render(template_subst_dict)

    def _generatePassword(self): \
            # pylint: disable=no-self-use
        # Generate a random password, used when creating a Kickstart file
        # for package-based node provisioning.
        strlength = 8
        strchars = string.ascii_letters + string.digits
        rootpw = ''.join([choice(strchars) for _ in range(strlength)])
        rootpw = crypt.crypt(str(rootpw), str(time.time()))
        return rootpw

    def __get_partition_mountpoint(self, dbPartition): \
            # pylint: disable=no-self-use
        if not dbPartition.mountPoint:
            if dbPartition.fsType == 'swap':
                mountPoint = 'swap'
            else:
                # Any partition that does not have a mountpoint defined
                # is ignored.
                return None
        else:
            mountPoint = dbPartition.mountPoint

        return mountPoint

    def _processPartition(self, dbPartition): \
            # pylint: disable=no-self-use
        mountPoint = dbPartition.mountPoint \
            if dbPartition.mountPoint else \
            self.__get_partition_mountpoint(dbPartition)

        if not mountPoint:
            return ''

        result = ''

        # All partitions must have a mount point and partition type
        result = 'part %s --fstype %s' % (mountPoint, dbPartition.fsType)

        # This will throw an exception if the size stored in the
        # partition settings is not an integer.
        if dbPartition.size:
            result += ' --size=%d' % (dbPartition.size)
        else:
            # If partition size is not set or is zero, use '--recommended' flag
            if mountPoint == 'swap':
                result += ' --recommended'

        disk, part = dbPartition.device.split('.')

        optionsList = dbPartition.options.split(',') \
            if dbPartition.options else []

        if dbPartition.grow is not None:
            result += ' --grow'

            if dbPartition.maxSize is not None:
                result += ' --maxsize %d' % (dbPartition.maxSize)

        if optionsList:
            # Add the fs options...
            result += ' --fsoptions="%s"' % (','.join(optionsList))

        result += ' --noformat --onpart=${d%s:-nodisk}%s' % (disk, part) \
            if dbPartition.preserve else \
            ' --ondisk=${d%s:-nodisk}' % str(disk)

        result += '\n'

        return result
Ejemplo n.º 16
0
class ParameterManager(TortugaObjectManager):
    def __init__(self):
        super(ParameterManager, self).__init__()

        self._globalParameterDbApi = GlobalParameterDbApi()

    def getParameter(self, session: Session, name: str) -> Parameter:
        """
        Raises:
            ParameterNotFound
        """

        return self._globalParameterDbApi.getParameter(session, name)

    def getBoolParameter(self,
                         session: Session,
                         name: str,
                         default: Optional[bool] = None) -> bool:
        """
        Raises:
            ParameterNotFound
            TortugaException
        """

        try:
            param = self.getParameter(session, name)
        except ParameterNotFound:
            if default is not None:
                return default

            raise

        return param.getValue() and \
            param.getValue()[0].lower() in ('1', 'y', 't')

    def getIntParameter(self,
                        session: Session,
                        name: str,
                        default: Optional[int] = None) -> int:
        """
        Raises:
            ParameterNotFound
            TortugaException
        """

        try:
            param = self.getParameter(name)
        except ParameterNotFound:
            if default is not None:
                return default

            raise

        return int(param.getValue())

    def getParameterList(self, session: Session) -> TortugaObjectList:
        return self._globalParameterDbApi.getParameterList(session)

    def upsertParameter(self, session: Session, parameter: Parameter) -> None:
        self._globalParameterDbApi.upsertParameter(session, parameter)

    def deleteParameter(self, session: Session, name: str) -> None:
        self._globalParameterDbApi.deleteParameter(session, name)
Ejemplo n.º 17
0
    def __init__(self, osFamilyInfo: OsFamilyInfo):
        super().__init__(osFamilyInfo)

        self._globalParameterDbApi = GlobalParameterDbApi()