Exemple #1
0
    def _delete_host_action(self, hardware_profile_name, software_profile_name,
                            action_name, *args, **kwargs):
        logger.debug('{}: {}, {}, {}, {}'.format(action_name,
                                                 hardware_profile_name,
                                                 software_profile_name, args,
                                                 kwargs))

        component_installers = self._get_enabled_component_installers(
            self._get_all_component_installers(base_kit_order='last'))

        from tortuga.db.dbManager import DbManager
        session = DbManager().openSession()

        #
        # Get all nodes marked as 'Deleted' that may still exist in the
        # database. We shouldn't have to do this, but occasionally a
        # transient condition (ie. unable to connect to hypervisor) occurs
        # and the delete node operation fails.
        #
        from tortuga.db.nodesDbHandler import NodesDbHandler
        nodes_db = NodesDbHandler()
        try:
            if software_profile_name:
                nodes = nodes_db.getNodeListByNodeStateAndSoftwareProfileName(
                    session, 'Deleted', software_profile_name)
            else:
                nodes = nodes_db.getNodesByNodeState(session, 'Deleted')

        finally:
            DbManager().closeSession()

        if 'nodes' in kwargs:
            aggregated_nodes = list(
                set(kwargs['nodes']) | set([node.name for node in nodes]))
            del kwargs['nodes']
        else:
            aggregated_nodes = nodes

        #
        # hardware profile currently undefined for delete_host() action,
        # so pass None as hardware profile name
        #
        self._run_action_with_node_list(component_installers,
                                        hardware_profile_name,
                                        software_profile_name,
                                        aggregated_nodes, action_name, *args,
                                        **kwargs)
Exemple #2
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()