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 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 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)
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)
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)