def setUp(self):
     dbConfigurator = DBConfigurator("")
     dbConfigurator.runSQLScript("SystemStatusDBTest",
                                 "./SystemStatusDBTest.sql")
     dbConfigurator.addUser("website", "cygnuscloud", "SystemStatusDBTest",
                            False)
     dbConfigurator.addUser("statusDBUpdater", "cygnuscloud",
                            "SystemStatusDBTest", True)
     self.__reader = SystemStatusDatabaseReader("website", "cygnuscloud",
                                                "SystemStatusDBTest")
     self.__reader.connect()
     self.__writer = SystemStatusDatabaseWriter("statusDBUpdater",
                                                "cygnuscloud",
                                                "SystemStatusDBTest")
     self.__writer.connect()
 def connectToDatabases(self, mysqlRootsPassword, statusDBName, commandsDBName, statusdbSQLFilePath, commandsDBSQLFilePath,
                        websiteUser, websiteUserPassword, endpointUser, endpointUserPassword):
     """
     Establishes a connection with the system status database.
     Args:
         mysqlRootsPassword: MySQL root's password
         statusDBName: the status database name
         statusdbSQLFilePath: the database schema definition SQL file path
         websiteUser: the website user's name. 
         websiteUserPassword: the website user's password
         endpointUser: the update user's name. This user will have ALL privileges on the status database.
         endpointUserPassword: the update user's password.
     """        
     # Create the status database
     self.__rootsPassword = mysqlRootsPassword
     self.__statusDatabaseName = statusDBName
     self.__commandsDatabaseName = commandsDBName
     configurator = DBConfigurator(mysqlRootsPassword)
     configurator.runSQLScript(statusDBName, statusdbSQLFilePath)
     configurator.runSQLScript(commandsDBName, commandsDBSQLFilePath)
     # Register the website and the endpoint users
     configurator.addUser(websiteUser, websiteUserPassword, statusDBName, False)
     configurator.addUser(endpointUser, endpointUserPassword, statusDBName, True)
     configurator.addUser(websiteUser, websiteUserPassword, commandsDBName, True)
     configurator.addUser(endpointUser, endpointUserPassword, commandsDBName, True)
     # Create the database connectors
     self.__commandsDBConnector = CommandsDatabaseConnector(endpointUser, endpointUserPassword, 
                                                            commandsDBName, 1) 
     self.__writer = SystemStatusDatabaseWriter(endpointUser, endpointUserPassword, statusDBName)
     # Connect to the database
     self.__writer.connect()
     self.__commandsDBConnector.connect()
 def setUp(self):
     dbConfigurator = DBConfigurator("")
     dbConfigurator.runSQLScript("SystemStatusDBTest", "./SystemStatusDBTest.sql")
     dbConfigurator.addUser("website", "cygnuscloud", "SystemStatusDBTest", False)
     dbConfigurator.addUser("statusDBUpdater", "cygnuscloud", "SystemStatusDBTest", True)
     self.__reader = SystemStatusDatabaseReader("website", "cygnuscloud", "SystemStatusDBTest")
     self.__reader.connect()
     self.__writer = SystemStatusDatabaseWriter("statusDBUpdater", "cygnuscloud", "SystemStatusDBTest")
     self.__writer.connect()
Example #4
0
 def connectToDatabases(self, mysqlRootsPassword, statusDBName,
                        commandsDBName, statusdbSQLFilePath,
                        commandsDBSQLFilePath, websiteUser,
                        websiteUserPassword, endpointUser,
                        endpointUserPassword):
     """
     Establishes a connection with the system status database.
     Args:
         mysqlRootsPassword: MySQL root's password
         statusDBName: the status database name
         statusdbSQLFilePath: the database schema definition SQL file path
         websiteUser: the website user's name. 
         websiteUserPassword: the website user's password
         endpointUser: the update user's name. This user will have ALL privileges on the status database.
         endpointUserPassword: the update user's password.
     """
     # Create the status database
     self.__rootsPassword = mysqlRootsPassword
     self.__statusDatabaseName = statusDBName
     self.__commandsDatabaseName = commandsDBName
     configurator = DBConfigurator(mysqlRootsPassword)
     configurator.runSQLScript(statusDBName, statusdbSQLFilePath)
     configurator.runSQLScript(commandsDBName, commandsDBSQLFilePath)
     # Register the website and the endpoint users
     configurator.addUser(websiteUser, websiteUserPassword, statusDBName,
                          False)
     configurator.addUser(endpointUser, endpointUserPassword, statusDBName,
                          True)
     configurator.addUser(websiteUser, websiteUserPassword, commandsDBName,
                          True)
     configurator.addUser(endpointUser, endpointUserPassword,
                          commandsDBName, True)
     # Create the database connectors
     self.__commandsDBConnector = CommandsDatabaseConnector(
         endpointUser, endpointUserPassword, commandsDBName, 1)
     self.__writer = SystemStatusDatabaseWriter(endpointUser,
                                                endpointUserPassword,
                                                statusDBName)
     # Connect to the database
     self.__writer.connect()
     self.__commandsDBConnector.connect()
Example #5
0
 def connectToDatabase(self, rootsPassword, databaseName, websiteUser,
                       websiteUserPassword, updateUser, updateUserPassword):
     # Create the status database
     self.__rootsPassword = rootsPassword
     self.__databaseName = databaseName
     configurator = DBConfigurator(rootsPassword)
     configurator.runSQLScript(databaseName,
                               "../../database/SystemStatusDB.sql")
     # Register the website and the update users
     configurator.addUser(websiteUser, websiteUserPassword, databaseName,
                          False)
     configurator.addUser(updateUser, updateUserPassword, databaseName,
                          True)
     # Create the database connectors
     self.__reader = SystemStatusDatabaseReader(websiteUser,
                                                websiteUserPassword,
                                                databaseName)
     self.__writer = SystemStatusDatabaseWriter(updateUser,
                                                updateUserPassword,
                                                databaseName)
     # Connect to the database
     self.__reader.connect()
     self.__writer.connect()
 def connectToDatabase(self, rootsPassword, databaseName, websiteUser, websiteUserPassword, updateUser, updateUserPassword):
     # Create the status database
     self.__rootsPassword = rootsPassword
     self.__databaseName = databaseName
     configurator = DBConfigurator(rootsPassword)
     configurator.runSQLScript(databaseName, "../../database/SystemStatusDB.sql")
     # Register the website and the update users
     configurator.addUser(websiteUser, websiteUserPassword, databaseName, False)
     configurator.addUser(updateUser, updateUserPassword, databaseName, True)
     # Create the database connectors
     self.__reader = SystemStatusDatabaseReader(websiteUser, websiteUserPassword, databaseName)
     self.__writer = SystemStatusDatabaseWriter(updateUser, updateUserPassword, databaseName)
     # Connect to the database
     self.__reader.connect()
     self.__writer.connect()
class Test(unittest.TestCase):
    def setUp(self):
        dbConfigurator = DBConfigurator("")
        dbConfigurator.runSQLScript("SystemStatusDBTest",
                                    "./SystemStatusDBTest.sql")
        dbConfigurator.addUser("website", "cygnuscloud", "SystemStatusDBTest",
                               False)
        dbConfigurator.addUser("statusDBUpdater", "cygnuscloud",
                               "SystemStatusDBTest", True)
        self.__reader = SystemStatusDatabaseReader("website", "cygnuscloud",
                                                   "SystemStatusDBTest")
        self.__reader.connect()
        self.__writer = SystemStatusDatabaseWriter("statusDBUpdater",
                                                   "cygnuscloud",
                                                   "SystemStatusDBTest")
        self.__writer.connect()

    def tearDown(self):
        self.__reader.disconnect()
        self.__writer.disconnect()
        dbConfigurator = DBConfigurator("")
        dbConfigurator.dropDatabase("SystemStatusDBTest")

    def testUpdateVMServerData(self):
        segment1Data = [('Server1', 'Ready', 'IP1', 1)]
        segment2Data = [('Server2', 'Booting', 'IP2', 1)]
        self.__writer.processVMServerSegment(1, 2, segment1Data)
        serversData = self.__reader.getVMServersData()
        self.assertEquals(serversData, [],
                          "processVMServerSegment does not work")
        self.__writer.processVMServerSegment(2, 2, segment2Data)
        serversData = self.__reader.getVMServersData()
        d2 = {
            "VMServerName": "Server2",
            "VMServerStatus": "Booting",
            "VMServerIP": "IP2",
            "VMServerListenningPort": 1
        }
        d1 = {
            "VMServerName": "Server1",
            "VMServerStatus": "Ready",
            "VMServerIP": "IP1",
            "VMServerListenningPort": 1
        }
        self.assertEquals(serversData, [d1, d2],
                          "processVMServerSegment does not work")
        segment3Data = [("Server3", "Ready", "IP3", 1)]
        self.__writer.processVMServerSegment(1, 1, segment3Data)
        serversData = self.__reader.getVMServersData()
        d3 = {
            "VMServerName": "Server3",
            "VMServerStatus": "Ready",
            "VMServerIP": "IP3",
            "VMServerListenningPort": 1
        }
        self.assertEquals(serversData, [d3],
                          "processVMServerSegment does not work")
        segment4Data = [("Server3", "Ready", "IP3", 1),
                        ("Server4", "Ready", "IP4", 1)]
        self.__writer.processVMServerSegment(1, 1, segment4Data)
        serversData = self.__reader.getVMServersData()
        self.assertEquals(serversData, [d3],
                          "processVMServerSegment does not work")

    def testUpdateVMDistributionData(self):
        segment1Data = [('Server1', 1), ('Server1', 2), ('Server1', 3)]
        segment2Data = [('Server2', 1), ('Server2', 4), ('Server2', 5)]
        self.__writer.processVMDistributionSegment(1, 2, segment1Data)
        serversData = self.__reader.getVMServersData()
        self.assertEquals(serversData, [],
                          "processVMDistributionSegment does not work")
        self.__writer.processVMDistributionSegment(2, 2, segment2Data)
        serversData = self.__reader.getVMDistributionData()
        d1 = {"VMServerName": "Server1", "VMID": 1}
        d2 = {"VMServerName": "Server1", "VMID": 2}
        d3 = {"VMServerName": "Server1", "VMID": 3}
        d4 = {"VMServerName": "Server2", "VMID": 1}
        d5 = {"VMServerName": "Server2", "VMID": 4}
        d6 = {"VMServerName": "Server2", "VMID": 5}
        self.assertEquals(serversData, [d1, d2, d3, d4, d5, d6],
                          "processVMDistributionSegment does not work")
        segment3Data = [('Server4', 10)]
        self.__writer.processVMDistributionSegment(1, 1, segment3Data)
        serversData = self.__reader.getVMDistributionData()
        d1 = {"VMServerName": "Server4", "VMID": 10}
        self.assertEquals(serversData, [d1],
                          "processVMDistributionSegment does not work")

    def testUpdateActiveVMData(self):
        segment1Data = [('Server1', 'Ready', 'IP1', 1)]
        self.__writer.processVMServerSegment(1, 1, segment1Data)
        segment1Data = [(1, 1, 'Debian1', 15800, 'Password')]
        segment2Data = [(2, 1, 'Debian1', 15802, 'Password')]
        self.__writer.processActiveVMSegment(1, 2, 'IP1', segment1Data)
        self.__writer.processActiveVMSegment(2, 2, 'IP1', segment2Data)
        result = self.__reader.getActiveVMsData(True)
        expectedResult = [{
            "VMServerName": "Server1",
            "UserID": 2,
            "VMID": 1,
            "VMName": "Debian1",
            "VNCPort": 15802,
            "VNCPassword": "******"
        }, {
            "VMServerName": "Server1",
            "UserID": 1,
            "VMID": 1,
            "VMName": "Debian1",
            "VNCPort": 15800,
            "VNCPassword": "******"
        }]
        self.assertEquals(result, expectedResult,
                          "processVMServerSegment does not work")
        result = self.__reader.getActiveVMsData(True)
        expectedResult = [{
            "VMServerName": "Server1",
            "UserID": 1,
            "VMID": 1,
            "VMName": "Debian1",
            "VNCPort": 15800,
            "VNCPassword": "******"
        }]

        self.assertEquals(result, expectedResult,
                          "getActiveVMsData does not work")
class Test(unittest.TestCase):      

    def setUp(self):
        dbConfigurator = DBConfigurator("")
        dbConfigurator.runSQLScript("SystemStatusDBTest", "./SystemStatusDBTest.sql")
        dbConfigurator.addUser("website", "cygnuscloud", "SystemStatusDBTest", False)
        dbConfigurator.addUser("statusDBUpdater", "cygnuscloud", "SystemStatusDBTest", True)
        self.__reader = SystemStatusDatabaseReader("website", "cygnuscloud", "SystemStatusDBTest")
        self.__reader.connect()
        self.__writer = SystemStatusDatabaseWriter("statusDBUpdater", "cygnuscloud", "SystemStatusDBTest")
        self.__writer.connect()

    def tearDown(self):
        self.__reader.disconnect()
        self.__writer.disconnect()
        dbConfigurator = DBConfigurator("")
        dbConfigurator.dropDatabase("SystemStatusDBTest")

    def testUpdateVMServerData(self):
        segment1Data = [('Server1', 'Ready', 'IP1', 1)]
        segment2Data = [('Server2', 'Booting', 'IP2', 1)]
        self.__writer.processVMServerSegment(1, 2, segment1Data)
        serversData = self.__reader.getVMServersData()
        self.assertEquals(serversData, [], "processVMServerSegment does not work")
        self.__writer.processVMServerSegment(2, 2, segment2Data)
        serversData = self.__reader.getVMServersData()        
        d2 = {"VMServerName":"Server2", "VMServerStatus":"Booting", "VMServerIP":"IP2", "VMServerListenningPort":1}
        d1 = {"VMServerName":"Server1", "VMServerStatus":"Ready", "VMServerIP":"IP1", "VMServerListenningPort":1}
        self.assertEquals(serversData, [d1,d2], "processVMServerSegment does not work")
        segment3Data = [("Server3", "Ready", "IP3", 1)]
        self.__writer.processVMServerSegment(1, 1, segment3Data)
        serversData = self.__reader.getVMServersData()
        d3 = {"VMServerName":"Server3", "VMServerStatus":"Ready", "VMServerIP":"IP3", "VMServerListenningPort":1}
        self.assertEquals(serversData, [d3], "processVMServerSegment does not work")
        segment4Data =[("Server3", "Ready", "IP3", 1), ("Server4", "Ready", "IP4", 1)]
        self.__writer.processVMServerSegment(1, 1, segment4Data)
        serversData = self.__reader.getVMServersData()
        self.assertEquals(serversData, [d3], "processVMServerSegment does not work")
        
    def testUpdateVMDistributionData(self):
        segment1Data = [('Server1', 1), ('Server1', 2), ('Server1', 3)]
        segment2Data = [('Server2', 1), ('Server2', 4), ('Server2', 5)]
        self.__writer.processVMDistributionSegment(1, 2, segment1Data)
        serversData = self.__reader.getVMServersData()
        self.assertEquals(serversData, [], "processVMDistributionSegment does not work")
        self.__writer.processVMDistributionSegment(2, 2, segment2Data)
        serversData = self.__reader.getVMDistributionData()
        d1 = {"VMServerName":"Server1", "VMID":1}
        d2 = {"VMServerName":"Server1", "VMID":2}
        d3 = {"VMServerName":"Server1", "VMID":3}
        d4 = {"VMServerName":"Server2", "VMID":1}
        d5 = {"VMServerName":"Server2", "VMID":4}
        d6 = {"VMServerName":"Server2", "VMID":5}
        self.assertEquals(serversData, [d1,d2,d3,d4,d5,d6], "processVMDistributionSegment does not work")
        segment3Data = [('Server4', 10)]
        self.__writer.processVMDistributionSegment(1, 1, segment3Data)
        serversData = self.__reader.getVMDistributionData()
        d1 = {"VMServerName":"Server4", "VMID":10}
        self.assertEquals(serversData, [d1], "processVMDistributionSegment does not work")
        
    def testUpdateActiveVMData(self):
        segment1Data = [('Server1', 'Ready', 'IP1', 1)]
        self.__writer.processVMServerSegment(1, 1, segment1Data)
        segment1Data = [(1, 1, 'Debian1', 15800, 'Password')]
        segment2Data = [(2, 1, 'Debian1', 15802, 'Password')]
        self.__writer.processActiveVMSegment(1, 2, 'IP1', segment1Data)
        self.__writer.processActiveVMSegment(2, 2, 'IP1', segment2Data)
        result = self.__reader.getActiveVMsData(True)
        expectedResult = [
            {"VMServerName" : "Server1", "UserID" : 2, "VMID" : 1, "VMName" : "Debian1", "VNCPort" : 15802, "VNCPassword" : "Password" },
            {"VMServerName" : "Server1", "UserID" : 1, "VMID" : 1, "VMName" : "Debian1", "VNCPort" : 15800, "VNCPassword" : "Password" }
            ]
        self.assertEquals(result, expectedResult, "processVMServerSegment does not work")
        result = self.__reader.getActiveVMsData(True)
        expectedResult = [
            {"VMServerName" : "Server1", "UserID" : 1, "VMID" : 1, "VMName" : "Debian1", "VNCPort" : 15800, "VNCPassword" : "Password" }
            ]
            
        self.assertEquals(result, expectedResult, "getActiveVMsData does not work")
class WebServerEndpoint(object):  
    """
    These objects communicate a cluster server and the web connectors.
    """    
    def __init__(self):
        """
        Initializes the endpoint's state
        Args:
            None
        """
        self.__stopped = False
    
    def connectToDatabases(self, mysqlRootsPassword, statusDBName, commandsDBName, statusdbSQLFilePath, commandsDBSQLFilePath,
                           websiteUser, websiteUserPassword, endpointUser, endpointUserPassword):
        """
        Establishes a connection with the system status database.
        Args:
            mysqlRootsPassword: MySQL root's password
            statusDBName: the status database name
            statusdbSQLFilePath: the database schema definition SQL file path
            websiteUser: the website user's name. 
            websiteUserPassword: the website user's password
            endpointUser: the update user's name. This user will have ALL privileges on the status database.
            endpointUserPassword: the update user's password.
        """        
        # Create the status database
        self.__rootsPassword = mysqlRootsPassword
        self.__statusDatabaseName = statusDBName
        self.__commandsDatabaseName = commandsDBName
        configurator = DBConfigurator(mysqlRootsPassword)
        configurator.runSQLScript(statusDBName, statusdbSQLFilePath)
        configurator.runSQLScript(commandsDBName, commandsDBSQLFilePath)
        # Register the website and the endpoint users
        configurator.addUser(websiteUser, websiteUserPassword, statusDBName, False)
        configurator.addUser(endpointUser, endpointUserPassword, statusDBName, True)
        configurator.addUser(websiteUser, websiteUserPassword, commandsDBName, True)
        configurator.addUser(endpointUser, endpointUserPassword, commandsDBName, True)
        # Create the database connectors
        self.__commandsDBConnector = CommandsDatabaseConnector(endpointUser, endpointUserPassword, 
                                                               commandsDBName, 1) 
        self.__writer = SystemStatusDatabaseWriter(endpointUser, endpointUserPassword, statusDBName)
        # Connect to the database
        self.__writer.connect()
        self.__commandsDBConnector.connect()
        
    def connectToClusterServer(self, certificatePath, clusterServerIP, clusterServerListenningPort, statusDBUpdateInterval):
        """
        Establishes a connection with the cluster server.
        Args:
            certificatePath: the server.crt and server.key directory path.
            clusterServerIP: the cluster server's IPv4 address
            clusterServerListenningPort: the cluster server's listenning port.
            statusDBUpdateInterval: the status database update interval (in seconds)
        Returns:
            Nothing
        """
        self.__manager = NetworkManager(certificatePath)
        self.__manager.startNetworkService()
        callback = _ClusterServerEndpointCallback(self)
        # Connect to the main server
        self.__clusterServerIP = clusterServerIP
        self.__clusterServerPort = clusterServerListenningPort
        self.__manager.connectTo(clusterServerIP, clusterServerListenningPort, 5, callback, True)
        while (not self.__manager.isConnectionReady(clusterServerIP, clusterServerListenningPort)) :
            sleep(0.1)
        # Create the packet handler
        self.__pHandler = ClusterServerPacketHandler(self.__manager)
        # Create the update thread
        self.__updateRequestThread = StatusDatabaseUpdateThread(_ClusterServerEndpointUpdateHandler(self), statusDBUpdateInterval)
        # Start it
        self.__updateRequestThread.start()
        
    def disconnectFromClusterServer(self):
        """
        Closes the connection with the cluster server and drops the databases.
        Args:
            haltVMServers: if True, the virtual machine servers will be halted immediately. If false, they will be
            halted until all their virtual machines have been shut down.
        Returns:
            Nothing
        @attention: DO NOT call this method inside a network thread (i.e. inside the web callback). If you do so,
        your application will hang.
        """
        # Send a halt packet to the cluster server
        p = self.__pHandler.createHaltPacket(self.__haltVMServers)
        self.__manager.sendPacket(self.__clusterServerIP, self.__clusterServerPort, p)
        # Stop the update request thread
        self.__updateRequestThread.stop()
        # Close the database connections
        self.__commandsDBConnector.disconnect()
        self.__writer.disconnect()
        # Stop the network service
        self.__manager.stopNetworkService()
        # Delete the status database
        dbConfigurator = DBConfigurator(self.__rootsPassword)
        dbConfigurator.dropDatabase(self.__statusDatabaseName)
        dbConfigurator.dropDatabase(self.__commandsDatabaseName)    
        
    def _processIncomingPacket(self, packet):
        """
        Processes an incoming package (sent from the cluster server).
        Args:
            packet: the packet to process
        Returns:
            Nothing
        """
        if (self.__stopped) :
            return
        data = self.__pHandler.readPacket(packet)
        if (data["packet_type"] == PACKET_T.VM_SERVERS_STATUS_DATA) :
            self.__writer.processVMServerSegment(data["Segment"], data["SequenceSize"], data["Data"])
        elif (data["packet_type"] == PACKET_T.VM_DISTRIBUTION_DATA) :
            self.__writer.processVMDistributionSegment(data["Segment"], data["SequenceSize"], data["Data"])
        elif (data["packet_type"] == PACKET_T.ACTIVE_VM_DATA) :
            self.__writer.processActiveVMSegment(data["Segment"], data["SequenceSize"], data["VMServerIP"], data["Data"])
        else :
            l = data["CommandID"].split("|")
            commandID = (int(l[0]), float(l[1]))
            if (data["packet_type"] == PACKET_T.COMMAND_EXECUTED) :
                self.__commandsDBConnector.removeExecutedCommand(commandID)
            else :           
                # Command outputs => serialize and add them to the commands database 
                if (data["packet_type"] == PACKET_T.VM_SERVER_BOOTUP_ERROR or 
                    data["packet_type"] == PACKET_T.VM_SERVER_UNREGISTRATION_ERROR or 
                    data["packet_type"] == PACKET_T.VM_SERVER_SHUTDOWN_ERROR) :
                    (outputType, outputContent) = CommandsHandler.createVMServerGenericErrorOutput(
                        data["packet_type"], data["ServerNameOrIPAddress"], data["ErrorMessage"])
                elif (data["packet_type"] == PACKET_T.VM_SERVER_REGISTRATION_ERROR) :
                    (outputType, outputContent) = CommandsHandler.createVMServerRegistrationErrorOutput(
                        data["VMServerIP"], data["VMServerPort"], data["VMServerName"], data["ErrorMessage"])
                elif (data["packet_type"] == PACKET_T.VM_BOOT_FAILURE) :
                    (outputType, outputContent) = CommandsHandler.createVMBootFailureErrorOutput(
                        data["VMID"], data["ErrorMessage"])  
                elif (data["packet_type"] == PACKET_T.VM_CONNECTION_DATA) :
                    (outputType, outputContent) = CommandsHandler.createVMConnectionDataOutput(
                        data["VNCServerIPAddress"], data["VNCServerPort"], data["VNCServerPassword"])
                self.__commandsDBConnector.addCommandOutput(commandID, outputType, outputContent)
                
    def processCommands(self):
        """
        Processes the commands sent from the web connectors.
        Args:
            None
        Returns:
            Nothing
        @attention: This method will only finish after processing a halt command.
        """
        while not self.__stopped :
            commandData = self.__commandsDBConnector.popCommand()
            if (commandData == None) :
                sleep(0.1)
            else :
                (commandID, commandType, commandArgs) = commandData
                parsedArgs = CommandsHandler.deserializeCommandArgs(commandType, commandArgs)
                if (commandType != COMMAND_TYPE.HALT) :
                    serializedCommandID = "{0}|{1}".format(commandID[0], commandID[1])                    
                    if (commandType == COMMAND_TYPE.BOOTUP_VM_SERVER) :                    
                        packet = self.__pHandler.createVMServerBootUpPacket(parsedArgs["VMServerNameOrIP"], serializedCommandID)
                    elif (commandType == COMMAND_TYPE.REGISTER_VM_SERVER) :
                        packet = self.__pHandler.createVMServerRegistrationPacket(parsedArgs["VMServerIP"], 
                            parsedArgs["VMServerPort"], parsedArgs["VMServerName"], serializedCommandID)
                    elif (commandType == COMMAND_TYPE.UNREGISTER_OR_SHUTDOWN_VM_SERVER) :
                        packet = self.__pHandler.createVMServerUnregistrationOrShutdownPacket(parsedArgs["VMServerNameOrIP"], 
                            parsedArgs["Halt"], parsedArgs["Unregister"], serializedCommandID)
                    elif (commandType == COMMAND_TYPE.VM_BOOT_REQUEST) :
                        packet = self.__pHandler.createVMBootRequestPacket(parsedArgs["VMID"], parsedArgs["UserID"], serializedCommandID)
                    self.__manager.sendPacket(self.__clusterServerIP, self.__clusterServerPort, packet)
                else :
                    self.__stopped = True
                    self.__haltVMServers = parsedArgs["HaltVMServers"]
    
    def _sendUpdateRequestPackets(self):
        """
        Sends the update request packets to the cluster server.
        Args:
            None
        Returns:
            Nothing
        """
        if (self.__stopped) :
            return
        # Send some update request packets to the cluster server
        p = self.__pHandler.createDataRequestPacket(PACKET_T.QUERY_VM_SERVERS_STATUS)
        self.__manager.sendPacket(self.__clusterServerIP, self.__clusterServerPort, p)        
        p = self.__pHandler.createDataRequestPacket(PACKET_T.QUERY_VM_DISTRIBUTION)
        self.__manager.sendPacket(self.__clusterServerIP, self.__clusterServerPort, p)
        p = self.__pHandler.createDataRequestPacket(PACKET_T.QUERY_ACTIVE_VM_DATA)
        self.__manager.sendPacket(self.__clusterServerIP, self.__clusterServerPort, p)
Example #10
0
class WebServerEndpoint(object):
    """
    These objects communicate a cluster server and the web connectors.
    """
    def __init__(self):
        """
        Initializes the endpoint's state
        Args:
            None
        """
        self.__stopped = False

    def connectToDatabases(self, mysqlRootsPassword, statusDBName,
                           commandsDBName, statusdbSQLFilePath,
                           commandsDBSQLFilePath, websiteUser,
                           websiteUserPassword, endpointUser,
                           endpointUserPassword):
        """
        Establishes a connection with the system status database.
        Args:
            mysqlRootsPassword: MySQL root's password
            statusDBName: the status database name
            statusdbSQLFilePath: the database schema definition SQL file path
            websiteUser: the website user's name. 
            websiteUserPassword: the website user's password
            endpointUser: the update user's name. This user will have ALL privileges on the status database.
            endpointUserPassword: the update user's password.
        """
        # Create the status database
        self.__rootsPassword = mysqlRootsPassword
        self.__statusDatabaseName = statusDBName
        self.__commandsDatabaseName = commandsDBName
        configurator = DBConfigurator(mysqlRootsPassword)
        configurator.runSQLScript(statusDBName, statusdbSQLFilePath)
        configurator.runSQLScript(commandsDBName, commandsDBSQLFilePath)
        # Register the website and the endpoint users
        configurator.addUser(websiteUser, websiteUserPassword, statusDBName,
                             False)
        configurator.addUser(endpointUser, endpointUserPassword, statusDBName,
                             True)
        configurator.addUser(websiteUser, websiteUserPassword, commandsDBName,
                             True)
        configurator.addUser(endpointUser, endpointUserPassword,
                             commandsDBName, True)
        # Create the database connectors
        self.__commandsDBConnector = CommandsDatabaseConnector(
            endpointUser, endpointUserPassword, commandsDBName, 1)
        self.__writer = SystemStatusDatabaseWriter(endpointUser,
                                                   endpointUserPassword,
                                                   statusDBName)
        # Connect to the database
        self.__writer.connect()
        self.__commandsDBConnector.connect()

    def connectToClusterServer(self, certificatePath, clusterServerIP,
                               clusterServerListenningPort,
                               statusDBUpdateInterval):
        """
        Establishes a connection with the cluster server.
        Args:
            certificatePath: the server.crt and server.key directory path.
            clusterServerIP: the cluster server's IPv4 address
            clusterServerListenningPort: the cluster server's listenning port.
            statusDBUpdateInterval: the status database update interval (in seconds)
        Returns:
            Nothing
        """
        self.__manager = NetworkManager(certificatePath)
        self.__manager.startNetworkService()
        callback = _ClusterServerEndpointCallback(self)
        # Connect to the main server
        self.__clusterServerIP = clusterServerIP
        self.__clusterServerPort = clusterServerListenningPort
        self.__manager.connectTo(clusterServerIP, clusterServerListenningPort,
                                 5, callback, True)
        while (not self.__manager.isConnectionReady(
                clusterServerIP, clusterServerListenningPort)):
            sleep(0.1)
        # Create the packet handler
        self.__pHandler = ClusterServerPacketHandler(self.__manager)
        # Create the update thread
        self.__updateRequestThread = StatusDatabaseUpdateThread(
            _ClusterServerEndpointUpdateHandler(self), statusDBUpdateInterval)
        # Start it
        self.__updateRequestThread.start()

    def disconnectFromClusterServer(self):
        """
        Closes the connection with the cluster server and drops the databases.
        Args:
            haltVMServers: if True, the virtual machine servers will be halted immediately. If false, they will be
            halted until all their virtual machines have been shut down.
        Returns:
            Nothing
        @attention: DO NOT call this method inside a network thread (i.e. inside the web callback). If you do so,
        your application will hang.
        """
        # Send a halt packet to the cluster server
        p = self.__pHandler.createHaltPacket(self.__haltVMServers)
        self.__manager.sendPacket(self.__clusterServerIP,
                                  self.__clusterServerPort, p)
        # Stop the update request thread
        self.__updateRequestThread.stop()
        # Close the database connections
        self.__commandsDBConnector.disconnect()
        self.__writer.disconnect()
        # Stop the network service
        self.__manager.stopNetworkService()
        # Delete the status database
        dbConfigurator = DBConfigurator(self.__rootsPassword)
        dbConfigurator.dropDatabase(self.__statusDatabaseName)
        dbConfigurator.dropDatabase(self.__commandsDatabaseName)

    def _processIncomingPacket(self, packet):
        """
        Processes an incoming package (sent from the cluster server).
        Args:
            packet: the packet to process
        Returns:
            Nothing
        """
        if (self.__stopped):
            return
        data = self.__pHandler.readPacket(packet)
        if (data["packet_type"] == PACKET_T.VM_SERVERS_STATUS_DATA):
            self.__writer.processVMServerSegment(data["Segment"],
                                                 data["SequenceSize"],
                                                 data["Data"])
        elif (data["packet_type"] == PACKET_T.VM_DISTRIBUTION_DATA):
            self.__writer.processVMDistributionSegment(data["Segment"],
                                                       data["SequenceSize"],
                                                       data["Data"])
        elif (data["packet_type"] == PACKET_T.ACTIVE_VM_DATA):
            self.__writer.processActiveVMSegment(data["Segment"],
                                                 data["SequenceSize"],
                                                 data["VMServerIP"],
                                                 data["Data"])
        else:
            l = data["CommandID"].split("|")
            commandID = (int(l[0]), float(l[1]))
            if (data["packet_type"] == PACKET_T.COMMAND_EXECUTED):
                self.__commandsDBConnector.removeExecutedCommand(commandID)
            else:
                # Command outputs => serialize and add them to the commands database
                if (data["packet_type"] == PACKET_T.VM_SERVER_BOOTUP_ERROR
                        or data["packet_type"]
                        == PACKET_T.VM_SERVER_UNREGISTRATION_ERROR
                        or data["packet_type"]
                        == PACKET_T.VM_SERVER_SHUTDOWN_ERROR):
                    (outputType, outputContent
                     ) = CommandsHandler.createVMServerGenericErrorOutput(
                         data["packet_type"], data["ServerNameOrIPAddress"],
                         data["ErrorMessage"])
                elif (data["packet_type"] ==
                      PACKET_T.VM_SERVER_REGISTRATION_ERROR):
                    (outputType, outputContent
                     ) = CommandsHandler.createVMServerRegistrationErrorOutput(
                         data["VMServerIP"], data["VMServerPort"],
                         data["VMServerName"], data["ErrorMessage"])
                elif (data["packet_type"] == PACKET_T.VM_BOOT_FAILURE):
                    (outputType, outputContent
                     ) = CommandsHandler.createVMBootFailureErrorOutput(
                         data["VMID"], data["ErrorMessage"])
                elif (data["packet_type"] == PACKET_T.VM_CONNECTION_DATA):
                    (outputType, outputContent
                     ) = CommandsHandler.createVMConnectionDataOutput(
                         data["VNCServerIPAddress"], data["VNCServerPort"],
                         data["VNCServerPassword"])
                self.__commandsDBConnector.addCommandOutput(
                    commandID, outputType, outputContent)

    def processCommands(self):
        """
        Processes the commands sent from the web connectors.
        Args:
            None
        Returns:
            Nothing
        @attention: This method will only finish after processing a halt command.
        """
        while not self.__stopped:
            commandData = self.__commandsDBConnector.popCommand()
            if (commandData == None):
                sleep(0.1)
            else:
                (commandID, commandType, commandArgs) = commandData
                parsedArgs = CommandsHandler.deserializeCommandArgs(
                    commandType, commandArgs)
                if (commandType != COMMAND_TYPE.HALT):
                    serializedCommandID = "{0}|{1}".format(
                        commandID[0], commandID[1])
                    if (commandType == COMMAND_TYPE.BOOTUP_VM_SERVER):
                        packet = self.__pHandler.createVMServerBootUpPacket(
                            parsedArgs["VMServerNameOrIP"],
                            serializedCommandID)
                    elif (commandType == COMMAND_TYPE.REGISTER_VM_SERVER):
                        packet = self.__pHandler.createVMServerRegistrationPacket(
                            parsedArgs["VMServerIP"],
                            parsedArgs["VMServerPort"],
                            parsedArgs["VMServerName"], serializedCommandID)
                    elif (commandType ==
                          COMMAND_TYPE.UNREGISTER_OR_SHUTDOWN_VM_SERVER):
                        packet = self.__pHandler.createVMServerUnregistrationOrShutdownPacket(
                            parsedArgs["VMServerNameOrIP"], parsedArgs["Halt"],
                            parsedArgs["Unregister"], serializedCommandID)
                    elif (commandType == COMMAND_TYPE.VM_BOOT_REQUEST):
                        packet = self.__pHandler.createVMBootRequestPacket(
                            parsedArgs["VMID"], parsedArgs["UserID"],
                            serializedCommandID)
                    self.__manager.sendPacket(self.__clusterServerIP,
                                              self.__clusterServerPort, packet)
                else:
                    self.__stopped = True
                    self.__haltVMServers = parsedArgs["HaltVMServers"]

    def _sendUpdateRequestPackets(self):
        """
        Sends the update request packets to the cluster server.
        Args:
            None
        Returns:
            Nothing
        """
        if (self.__stopped):
            return
        # Send some update request packets to the cluster server
        p = self.__pHandler.createDataRequestPacket(
            PACKET_T.QUERY_VM_SERVERS_STATUS)
        self.__manager.sendPacket(self.__clusterServerIP,
                                  self.__clusterServerPort, p)
        p = self.__pHandler.createDataRequestPacket(
            PACKET_T.QUERY_VM_DISTRIBUTION)
        self.__manager.sendPacket(self.__clusterServerIP,
                                  self.__clusterServerPort, p)
        p = self.__pHandler.createDataRequestPacket(
            PACKET_T.QUERY_ACTIVE_VM_DATA)
        self.__manager.sendPacket(self.__clusterServerIP,
                                  self.__clusterServerPort, p)
class MainServerConnector(object):    

    def __init__(self, callback):
        self.__stopped = False
        self.__callback = callback
    
    def connectToDatabase(self, rootsPassword, databaseName, websiteUser, websiteUserPassword, updateUser, updateUserPassword):
        # Create the status database
        self.__rootsPassword = rootsPassword
        self.__databaseName = databaseName
        configurator = DBConfigurator(rootsPassword)
        configurator.runSQLScript(databaseName, "../../database/SystemStatusDB.sql")
        # Register the website and the update users
        configurator.addUser(websiteUser, websiteUserPassword, databaseName, False)
        configurator.addUser(updateUser, updateUserPassword, databaseName, True)
        # Create the database connectors
        self.__reader = SystemStatusDatabaseReader(websiteUser, websiteUserPassword, databaseName)
        self.__writer = SystemStatusDatabaseWriter(updateUser, updateUserPassword, databaseName)
        # Connect to the database
        self.__reader.connect()
        self.__writer.connect()
        
    def connectToMainServer(self, certificatePath, mainServerIP, mainServerListenningPort):
        self.__manager = NetworkManager(certificatePath)
        self.__manager.startNetworkService()
        callback = _MainServerConnectorCallback(self)
        # Connect to the main server
        self.__mainServerPort = mainServerListenningPort
        self.__manager.connectTo(mainServerIP, mainServerListenningPort, 5, callback, True)
        while (not self.__manager.isConnectionReady(mainServerListenningPort)) :
            sleep(0.1)
        # Create the packet handler
        self.__pHandler = MainServerPacketHandler(self.__manager)
        # Create the update thread
        self.__updateRequestThread = StatusDatabaseUpdateThread(_MainServerConnectorUpdateHandler(self), 20)
        # Start it
        self.__updateRequestThread.start()
        
    def disconnectFromMainServer(self):
        # Discard all the incoming packets and the scheduled updates
        self.__stopped = True
        # Stop the update request thread
        self.__updateRequestThread.stop()
        # Close the database connections
        self.__reader.disconnect()
        self.__writer.disconnect()
        # Stop the network service
        self.__manager.stopNetworkService()
        # Delete the status database
        dbConfigurator = DBConfigurator(self.__rootsPassword)
        dbConfigurator.dropDatabase(self.__databaseName)
        
    def getImages(self):
        return self.__reader.getImages()
        
    def getVMServersData(self):
        return self.__reader.getVMServersData()
    
    def registerVMServer(self, vmServerIP, vmServerPort, vmServerName):
        p = self.__pHandler.createVMServerRegistrationPacket(vmServerIP, vmServerPort, vmServerName)
        self.__manager.sendPacket(self.__mainServerPort, p)
        
    def unregisterVMServer(self, vmServerNameOrIP, halt):
        p = self.__pHandler.createVMServerUnregistrationOrShutdownPacket(vmServerNameOrIP, halt, False)
        self.__manager.sendPacket(self.__mainServerPort, p)
        
    def bootUpVMServer(self, vmServerNameOrIP):
        p = self.__pHandler.createVMServerBootUpPacket(vmServerNameOrIP)
        self.__manager.sendPacket(self.__mainServerPort, p)
        
    def shutdownVMServer(self, vmServerNameOrIP, halt):
        p = self.__pHandler.createVMServerUnregistrationOrShutdownPacket(vmServerNameOrIP, halt, True)
        self.__manager.sendPacket(self.__mainServerPort, p)
        
    def bootUpVirtualMachine(self, imageName, userID):
        p = self.__pHandler.createVMBootRequestPacket(imageName, userID)
        self.__manager.sendPacket(self.__mainServerPort, p)
        
    def _processIncomingPacket(self, packet):
        if (self.__stopped) :
            return
        data = self.__pHandler.readPacket(packet)
        if (data["packet_type"] == PACKET_T.VM_SERVERS_STATUS_DATA) :
            self.__writer.processVMServerSegment(data["Segment"], data["SequenceSize"], data["Data"])
        elif (data["packet_type"] == PACKET_T.AVAILABLE_IMAGES_DATA) :
            self.__writer.processImageSegment(data["Segment"], data["SequenceSize"], data["Data"])
        elif (data["packet_type"] == PACKET_T.VM_SERVER_BOOTUP_ERROR) :
            self.__callback.handleVMServerBootUpError(data["ServerNameOrIPAddress"], data["ErrorMessage"])
        elif (data["packet_type"] == PACKET_T.VM_SERVER_REGISTRATION_ERROR) :
            self.__callback.handleVMServerRegistrationError(data["ServerNameOrIPAddress"], data["ErrorMessage"])  
        elif (data["packet_type"] == PACKET_T.VM_BOOT_FAILURE) :
            self.__callback.handleVMBootFailure(data["VMName"], data["UserID"], data["ErrorMessage"])  
        elif (data["packet_type"] == PACKET_T.VM_CONNECTION_DATA) :
            self.__callback.handleVMConnectionData(data["UserID"], data["VNCServerIPAddress"], data["VNCServerPort"],
                                                   data["VNCServerPassword"])
    
    def _sendUpdateRequestPackets(self):
        if (self.__stopped) :
            return
        # Send some update request packets to the main server
        p = self.__pHandler.createDataRequestPacket(PACKET_T.QUERY_VM_SERVERS_STATUS)
        self.__manager.sendPacket(self.__mainServerPort, p)
        p = self.__pHandler.createDataRequestPacket(PACKET_T.QUERY_AVAILABLE_IMAGES)
        self.__manager.sendPacket(self.__mainServerPort, p)
Example #12
0
class MainServerConnector(object):
    def __init__(self, callback):
        self.__stopped = False
        self.__callback = callback

    def connectToDatabase(self, rootsPassword, databaseName, websiteUser,
                          websiteUserPassword, updateUser, updateUserPassword):
        # Create the status database
        self.__rootsPassword = rootsPassword
        self.__databaseName = databaseName
        configurator = DBConfigurator(rootsPassword)
        configurator.runSQLScript(databaseName,
                                  "../../database/SystemStatusDB.sql")
        # Register the website and the update users
        configurator.addUser(websiteUser, websiteUserPassword, databaseName,
                             False)
        configurator.addUser(updateUser, updateUserPassword, databaseName,
                             True)
        # Create the database connectors
        self.__reader = SystemStatusDatabaseReader(websiteUser,
                                                   websiteUserPassword,
                                                   databaseName)
        self.__writer = SystemStatusDatabaseWriter(updateUser,
                                                   updateUserPassword,
                                                   databaseName)
        # Connect to the database
        self.__reader.connect()
        self.__writer.connect()

    def connectToMainServer(self, certificatePath, mainServerIP,
                            mainServerListenningPort):
        self.__manager = NetworkManager(certificatePath)
        self.__manager.startNetworkService()
        callback = _MainServerConnectorCallback(self)
        # Connect to the main server
        self.__mainServerPort = mainServerListenningPort
        self.__manager.connectTo(mainServerIP, mainServerListenningPort, 5,
                                 callback, True)
        while (not self.__manager.isConnectionReady(mainServerListenningPort)):
            sleep(0.1)
        # Create the packet handler
        self.__pHandler = MainServerPacketHandler(self.__manager)
        # Create the update thread
        self.__updateRequestThread = StatusDatabaseUpdateThread(
            _MainServerConnectorUpdateHandler(self), 20)
        # Start it
        self.__updateRequestThread.start()

    def disconnectFromMainServer(self):
        # Discard all the incoming packets and the scheduled updates
        self.__stopped = True
        # Stop the update request thread
        self.__updateRequestThread.stop()
        # Close the database connections
        self.__reader.disconnect()
        self.__writer.disconnect()
        # Stop the network service
        self.__manager.stopNetworkService()
        # Delete the status database
        dbConfigurator = DBConfigurator(self.__rootsPassword)
        dbConfigurator.dropDatabase(self.__databaseName)

    def getImages(self):
        return self.__reader.getImages()

    def getVMServersData(self):
        return self.__reader.getVMServersData()

    def registerVMServer(self, vmServerIP, vmServerPort, vmServerName):
        p = self.__pHandler.createVMServerRegistrationPacket(
            vmServerIP, vmServerPort, vmServerName)
        self.__manager.sendPacket(self.__mainServerPort, p)

    def unregisterVMServer(self, vmServerNameOrIP, halt):
        p = self.__pHandler.createVMServerUnregistrationOrShutdownPacket(
            vmServerNameOrIP, halt, False)
        self.__manager.sendPacket(self.__mainServerPort, p)

    def bootUpVMServer(self, vmServerNameOrIP):
        p = self.__pHandler.createVMServerBootUpPacket(vmServerNameOrIP)
        self.__manager.sendPacket(self.__mainServerPort, p)

    def shutdownVMServer(self, vmServerNameOrIP, halt):
        p = self.__pHandler.createVMServerUnregistrationOrShutdownPacket(
            vmServerNameOrIP, halt, True)
        self.__manager.sendPacket(self.__mainServerPort, p)

    def bootUpVirtualMachine(self, imageName, userID):
        p = self.__pHandler.createVMBootRequestPacket(imageName, userID)
        self.__manager.sendPacket(self.__mainServerPort, p)

    def _processIncomingPacket(self, packet):
        if (self.__stopped):
            return
        data = self.__pHandler.readPacket(packet)
        if (data["packet_type"] == PACKET_T.VM_SERVERS_STATUS_DATA):
            self.__writer.processVMServerSegment(data["Segment"],
                                                 data["SequenceSize"],
                                                 data["Data"])
        elif (data["packet_type"] == PACKET_T.AVAILABLE_IMAGES_DATA):
            self.__writer.processImageSegment(data["Segment"],
                                              data["SequenceSize"],
                                              data["Data"])
        elif (data["packet_type"] == PACKET_T.VM_SERVER_BOOTUP_ERROR):
            self.__callback.handleVMServerBootUpError(
                data["ServerNameOrIPAddress"], data["ErrorMessage"])
        elif (data["packet_type"] == PACKET_T.VM_SERVER_REGISTRATION_ERROR):
            self.__callback.handleVMServerRegistrationError(
                data["ServerNameOrIPAddress"], data["ErrorMessage"])
        elif (data["packet_type"] == PACKET_T.VM_BOOT_FAILURE):
            self.__callback.handleVMBootFailure(data["VMName"], data["UserID"],
                                                data["ErrorMessage"])
        elif (data["packet_type"] == PACKET_T.VM_CONNECTION_DATA):
            self.__callback.handleVMConnectionData(data["UserID"],
                                                   data["VNCServerIPAddress"],
                                                   data["VNCServerPort"],
                                                   data["VNCServerPassword"])

    def _sendUpdateRequestPackets(self):
        if (self.__stopped):
            return
        # Send some update request packets to the main server
        p = self.__pHandler.createDataRequestPacket(
            PACKET_T.QUERY_VM_SERVERS_STATUS)
        self.__manager.sendPacket(self.__mainServerPort, p)
        p = self.__pHandler.createDataRequestPacket(
            PACKET_T.QUERY_AVAILABLE_IMAGES)
        self.__manager.sendPacket(self.__mainServerPort, p)