def __init__(self, dbConnector, networkManager, vmServerPacketHandler, clusterServerPacketHandler, imageRepositoryPacketHandler, vmServerCallback, listenningPort, repositoryIP, repositoryPort, loadBalancerSettings, averageCompressionRatio, useSSL): """ Initializes the reactor's state Args: dbConnector: a cluster server database connector networkManager: the network manager to use vmServerPacketHandler: the virtual machine server packet handler clusterServerPacketHandler: the cluster server packet handler imageRepositoryPacketHandler: the image repository packet handler vmServerCallback: the virtual machine server packet reactor listenningPort: the control connection's listenning port repositoryIP: the image repository's IP address repositoryPort: the image repository's port loadBalancerSettings: the load balancing algorithm settings averageCompressionRatio: the compression algorithm's average compression ratio useSSL: indicates if the network connections use SSL encryption or not """ self.__commandsDBConnector = dbConnector self.__networkManager = networkManager self.__vmServerPacketHandler = vmServerPacketHandler self.__packetHandler = clusterServerPacketHandler self.__imageRepositoryPacketHandler = imageRepositoryPacketHandler self.__loadBalancer = PenaltyBasedLoadBalancer(self.__commandsDBConnector, loadBalancerSettings[1], loadBalancerSettings[2], loadBalancerSettings[3], loadBalancerSettings[4], loadBalancerSettings[5]) self.__averageCompressionRatio = averageCompressionRatio self.__vmServerCallback = vmServerCallback self.__listenningPort = listenningPort self.__repositoryIP = repositoryIP self.__repositoryPort = repositoryPort self.__finished = False self.__useSSL = useSSL
def __init__(self, dbConnector, networkManager, vmServerPacketHandler, clusterServerPacketHandler, imageRepositoryPacketHandler, vmServerCallback, listenningPort, repositoryIP, repositoryPort, loadBalancerSettings, averageCompressionRatio, useSSL): """ Initializes the reactor's state Args: dbConnector: a cluster server database connector networkManager: the network manager to use vmServerPacketHandler: the virtual machine server packet handler clusterServerPacketHandler: the cluster server packet handler imageRepositoryPacketHandler: the image repository packet handler vmServerCallback: the virtual machine server packet reactor listenningPort: the control connection's listenning port repositoryIP: the image repository's IP address repositoryPort: the image repository's port loadBalancerSettings: the load balancing algorithm settings averageCompressionRatio: the compression algorithm's average compression ratio useSSL: indicates if the network connections use SSL encryption or not """ self.__commandsDBConnector = dbConnector self.__networkManager = networkManager self.__vmServerPacketHandler = vmServerPacketHandler self.__packetHandler = clusterServerPacketHandler self.__imageRepositoryPacketHandler = imageRepositoryPacketHandler self.__loadBalancer = PenaltyBasedLoadBalancer( self.__commandsDBConnector, loadBalancerSettings[1], loadBalancerSettings[2], loadBalancerSettings[3], loadBalancerSettings[4], loadBalancerSettings[5]) self.__averageCompressionRatio = averageCompressionRatio self.__vmServerCallback = vmServerCallback self.__listenningPort = listenningPort self.__repositoryIP = repositoryIP self.__repositoryPort = repositoryPort self.__finished = False self.__useSSL = useSSL
class EndpointPacketReactor(object): """ These objects process the packets sent from the cluster endpoint """ def __init__(self, dbConnector, networkManager, vmServerPacketHandler, clusterServerPacketHandler, imageRepositoryPacketHandler, vmServerCallback, listenningPort, repositoryIP, repositoryPort, loadBalancerSettings, averageCompressionRatio, useSSL): """ Initializes the reactor's state Args: dbConnector: a cluster server database connector networkManager: the network manager to use vmServerPacketHandler: the virtual machine server packet handler clusterServerPacketHandler: the cluster server packet handler imageRepositoryPacketHandler: the image repository packet handler vmServerCallback: the virtual machine server packet reactor listenningPort: the control connection's listenning port repositoryIP: the image repository's IP address repositoryPort: the image repository's port loadBalancerSettings: the load balancing algorithm settings averageCompressionRatio: the compression algorithm's average compression ratio useSSL: indicates if the network connections use SSL encryption or not """ self.__commandsDBConnector = dbConnector self.__networkManager = networkManager self.__vmServerPacketHandler = vmServerPacketHandler self.__packetHandler = clusterServerPacketHandler self.__imageRepositoryPacketHandler = imageRepositoryPacketHandler self.__loadBalancer = PenaltyBasedLoadBalancer( self.__commandsDBConnector, loadBalancerSettings[1], loadBalancerSettings[2], loadBalancerSettings[3], loadBalancerSettings[4], loadBalancerSettings[5]) self.__averageCompressionRatio = averageCompressionRatio self.__vmServerCallback = vmServerCallback self.__listenningPort = listenningPort self.__repositoryIP = repositoryIP self.__repositoryPort = repositoryPort self.__finished = False self.__useSSL = useSSL def processClusterEndpointIncomingPacket(self, packet): """ Processes a packet sent from the cluster endpoint Args: packet: the packet to process Returns: Nothing """ data = self.__packetHandler.readPacket(packet) if (data["packet_type"] == PACKET_T.REGISTER_VM_SERVER): self.__registerVMServer(data) elif (data["packet_type"] == PACKET_T.QUERY_VM_SERVERS_STATUS): self.__sendStatusData( self.__commandsDBConnector.getVMServerConfiguration, self.__packetHandler.createVMServerStatusPacket) elif (data["packet_type"] == PACKET_T.UNREGISTER_OR_SHUTDOWN_VM_SERVER ): self.__unregisterOrShutdownVMServer(data) elif (data["packet_type"] == PACKET_T.BOOTUP_VM_SERVER): self.__bootVMServer(data) elif (data["packet_type"] == PACKET_T.VM_BOOT_REQUEST): self.__bootVM(data) elif (data["packet_type"] == PACKET_T.HALT): self.__doImmediateShutdown(data) elif (data["packet_type"] == PACKET_T.QUERY_VM_DISTRIBUTION): self.__sendStatusData( self.__commandsDBConnector.getHostedImages, self.__packetHandler.createVMDistributionPacket) elif (data["packet_type"] == PACKET_T.QUERY_ACTIVE_VM_VNC_DATA): self.__requestVNCConnectionData() elif (data["packet_type"] == PACKET_T.DOMAIN_DESTRUCTION): self.__destroyOrRebootDomain(data, False) elif (data["packet_type"] == PACKET_T.DOMAIN_REBOOT): self.__destroyOrRebootDomain(data, True) elif (data["packet_type"] == PACKET_T.VM_SERVER_CONFIGURATION_CHANGE): self.__changeVMServerConfiguration(data) elif (data["packet_type"] == PACKET_T.QUERY_REPOSITORY_STATUS): self.__sendRepositoryStatusData() elif (data["packet_type"] == PACKET_T.DEPLOY_IMAGE or data["packet_type"] == PACKET_T.DELETE_IMAGE_FROM_SERVER): self.__deployOrDeleteImage(data) elif (data["packet_type"] == PACKET_T.CREATE_IMAGE or data["packet_type"] == PACKET_T.EDIT_IMAGE): self.__createOrEditImage(data) elif (data["packet_type"] == PACKET_T.DELETE_IMAGE_FROM_INFRASTRUCTURE ): self.__deleteImageFromInfrastructure(data) elif (data["packet_type"] == PACKET_T.AUTO_DEPLOY): self.__auto_deploy_image(data) elif (data["packet_type"] == PACKET_T.QUERY_VM_SERVERS_RESOURCE_USAGE): self.__sendStatusData( self.__commandsDBConnector.getVMServerStatisticsToSend, self.__packetHandler.createVMServerResourceUsagePacket) def __registerVMServer(self, data): """ Processes a virtual machine server registration packet Args: data: a dictionary containing the incoming packet's data Returns: Nothing """ try: # Comprobar si la IP y el nombre del servidor ya están en uso server_id = self.__commandsDBConnector.getVMServerID( data["VMServerIP"]) if (server_id != None): raise Exception("The IP address " + data["VMServerIP"] + " is assigned to another VM server") server_id = self.__commandsDBConnector.getVMServerID( data["VMServerName"]) if (server_id != None): raise Exception("The name " + data["VMServerName"] + " is assigned to another VM server") # Establecer la conexión self.__networkManager.connectTo(data["VMServerIP"], data["VMServerPort"], 20, self.__vmServerCallback, self.__useSSL, True) while not self.__networkManager.isConnectionReady( data["VMServerIP"], data["VMServerPort"]): sleep(0.1) # Registrar el nuevo servidor y pedirle su estado self.__commandsDBConnector.registerVMServer( data["VMServerName"], data["VMServerIP"], data["VMServerPort"], data["IsEditionServer"]) # Indicar al endpoint de la web que el comando se ha ejecutado con éxito p = self.__packetHandler.createCommandExecutedPacket( data["CommandID"]) except Exception: p = self.__packetHandler.createErrorPacket( PACKET_T.VM_SERVER_REGISTRATION_ERROR, ERROR_DESC_T.CLSRVR_VMSRVR_CONNECTION_ERROR, data["CommandID"]) self.__networkManager.sendPacket('', self.__listenningPort, p) def __bootVMServer(self, data): """ Processes a virtual machine server boot packet Args: data: a dictionary containing the incoming packet's data Returns: Nothing """ try: serverNameOrIPAddress = data["ServerNameOrIPAddress"] serverId = self.__commandsDBConnector.getVMServerID( serverNameOrIPAddress) if (serverId == None): p = self.__packetHandler.createErrorPacket( PACKET_T.VM_SERVER_BOOTUP_ERROR, ERROR_DESC_T.CLSRVR_UNKNOWN_VMSRVR, data["CommandID"]) else: serverData = self.__commandsDBConnector.getVMServerConfiguration( serverId) if (serverData["ServerStatus"] == SERVER_STATE_T.SHUT_DOWN or serverData["ServerStatus"] == SERVER_STATE_T.CONNECTION_TIMED_OUT): self.__networkManager.connectTo(serverData["ServerIP"], serverData["ServerPort"], 20, self.__vmServerCallback, self.__useSSL, True) while not self.__networkManager.isConnectionReady( serverData["ServerIP"], serverData["ServerPort"]): sleep(0.1) self.__commandsDBConnector.updateVMServerStatus( serverId, SERVER_STATE_T.BOOTING) imagesToDeploy = self.__commandsDBConnector.getHostedImagesInState( serverId, IMAGE_STATE_T.DEPLOY) for imageID in imagesToDeploy: familyID = self.__commandsDBConnector.getImageVMFamilyID( imageID) familyFeatures = self.__commandsDBConnector.getVMFamilyFeatures( familyID) p = self.__vmServerPacketHandler.createImageDeploymentPacket( self.__repositoryIP, self.__repositoryPort, imageID, self.__commandsDBConnector. getImageEditionCommandID(imageID)) self.__commandsDBConnector.allocateVMServerResources( data["CommandID"], serverId, 0, familyFeatures["osDiskSize"] + familyFeatures["dataDiskSize"], 0, 0, 1) self.__networkManager.sendPacket( serverData["ServerIP"], serverData["ServerPort"], p) imagesToDelete = self.__commandsDBConnector.getHostedImagesInState( serverId, IMAGE_STATE_T.DELETE) for imageID in imagesToDelete: p = self.__vmServerPacketHandler.createDeleteImagePacket( imageID, self.__commandsDBConnector. getImageDeletionCommandID(imageID)) self.__networkManager.sendPacket( serverData["ServerIP"], serverData["ServerPort"], p) p = self.__packetHandler.createCommandExecutedPacket( data["CommandID"]) except Exception: p = self.__packetHandler.createErrorPacket( PACKET_T.VM_SERVER_BOOTUP_ERROR, ERROR_DESC_T.CLSRVR_VMSRVR_CONNECTION_ERROR, data["CommandID"]) self.__networkManager.sendPacket('', self.__listenningPort, p) def __bootVM(self, data): """ Processes a virtual machine server boot packet Args: data: a dictionary containing the incoming packet's data Returns: Nothing """ vmID = data["VMID"] userID = data["UserID"] (serverID, errorDescription) = self.__loadBalancer.assignVMServer( vmID, MODE_T.BOOT_DOMAIN) if (errorDescription != None): p = self.__packetHandler.createErrorPacket( PACKET_T.VM_BOOT_FAILURE, errorDescription, data["CommandID"]) self.__networkManager.sendPacket('', self.__listenningPort, p) else: familyID = self.__commandsDBConnector.getImageVMFamilyID(vmID) familyFeatures = self.__commandsDBConnector.getVMFamilyFeatures( familyID) self.__commandsDBConnector.allocateVMServerResources( data["CommandID"], serverID, familyFeatures["RAMSize"], 0, familyFeatures["dataDiskSize"], familyFeatures["vCPUs"], 1) p = self.__vmServerPacketHandler.createVMBootPacket( vmID, userID, data["CommandID"]) serverData = self.__commandsDBConnector.getVMServerConfiguration( serverID) error = self.__networkManager.sendPacket(serverData["ServerIP"], serverData["ServerPort"], p) if (error != None): p = self.__packetHandler.createErrorPacket( PACKET_T.VM_BOOT_FAILURE, ERROR_DESC_T.CLSRVR_VMSRVR_CONNECTION_LOST, data["CommandID"]) self.__networkManager.sendPacket('', self.__listenningPort, p) self.__commandsDBConnector.freeVMServerResources( data["CommandID"], True) return self.__commandsDBConnector.registerActiveVMLocation( data["CommandID"], serverID) self.__commandsDBConnector.registerVMBootCommand( data["CommandID"], data["VMID"]) def __auto_deploy_image(self, data): """ Processes an image auto-deployment packet Args: data: a dictionary containing the incoming packet's data Returns: Nothing """ if (data["Instances"] == 0 or data["Instances"] < -1): p = self.__packetHandler.createCommandExecutedPacket( data["CommandID"]) self.__networkManager.sendPacket('', self.__listenningPort, p) return familyID = self.__commandsDBConnector.getImageVMFamilyID( data["ImageID"]) if (familyID == None): p = self.__packetHandler.createErrorPacket( PACKET_T.AUTO_DEPLOY_ERROR, ERROR_DESC_T.CLSRVR_UNKNOWN_IMAGE, data["CommandID"]) self.__networkManager.sendPacket('', self.__listenningPort, p) return familyFeatures = self.__commandsDBConnector.getVMFamilyFeatures( familyID) if (data["Instances"] == -1): if (not self.__commandsDBConnector.isBeingDeleted( data["ImageID"])): self.__commandsDBConnector.changeImageCopiesState( data["ImageID"], IMAGE_STATE_T.DEPLOY) serverIDs = self.__commandsDBConnector.getHosts( data["ImageID"], IMAGE_STATE_T.DEPLOY) if (serverIDs != []): self.__commandsDBConnector.addImageEditionCommand( data["CommandID"], data["ImageID"]) p = self.__vmServerPacketHandler.createImageDeploymentPacket( self.__repositoryIP, self.__repositoryPort, data["ImageID"], data["CommandID"]) for serverID in serverIDs: self.__commandsDBConnector.allocateVMServerResources( data["CommandID"], serverID, 0, familyFeatures["osDiskSize"] + familyFeatures["dataDiskSize"], 0, 0, 1) connectionData = self.__commandsDBConnector.getVMServerConfiguration( serverID) self.__networkManager.sendPacket( connectionData["ServerIP"], connectionData["ServerPort"], p) else: if (not self.__commandsDBConnector. isThereSomeImageCopyInState( data["ImageID"], IMAGE_STATE_T.EDITED)): p = self.__packetHandler.createCommandExecutedPacket( data["CommandID"]) self.__networkManager.sendPacket( '', self.__listenningPort, p) else: p = self.__packetHandler.createErrorPacket( PACKET_T.AUTO_DEPLOY_ERROR, ERROR_DESC_T.CLSRVR_NOT_EDITED_IMAGE, data["CommandID"]) self.__networkManager.sendPacket('', self.__listenningPort, p) elif (data["Instances"] > 0): if (self.__commandsDBConnector.isAffectedByAutoDeploymentCommand( data["ImageID"])): p = self.__packetHandler.createErrorPacket( PACKET_T.AUTO_DEPLOY_ERROR, ERROR_DESC_T.CLSRVR_AUTODEPLOYED, data["CommandID"]) self.__networkManager.sendPacket('', self.__listenningPort, p) return output = self.__loadBalancer.assignVMServer( data["ImageID"], MODE_T.DEPLOY_IMAGE) if (output[1] != None): p = self.__packetHandler.createErrorPacket( PACKET_T.AUTO_DEPLOY_ERROR, output[1], data["CommandID"]) self.__networkManager.sendPacket('', self.__listenningPort, p) else: if (output[2] < data["Instances"]): p = self.__packetHandler.createErrorPacket( PACKET_T.AUTO_DEPLOY_ERROR, ERROR_DESC_T.CLSRVR_AUTOD_TOO_MANY_INSTANCES, data["CommandID"]) self.__networkManager.sendPacket('', self.__listenningPort, p) else: servers = [] deployed_copies = 0 i = 0 while (deployed_copies < data["Instances"]): servers.append(output[i][0][0]) deployed_copies += output[i][0][1] i += 1 self.__commandsDBConnector.addAutoDeploymentCommand( data["CommandID"], data["ImageID"], len(servers)) p = self.__vmServerPacketHandler.createImageDeploymentPacket( self.__repositoryIP, self.__repositoryPort, data["ImageID"], data["CommandID"]) for serverID in servers: self.__commandsDBConnector.allocateVMServerResources( data["CommandID"], serverID, 0, familyFeatures["osDiskSize"] + familyFeatures["dataDiskSize"], 0, 0, 1) connectionData = self.__commandsDBConnector.getVMServerConfiguration( serverID) self.__networkManager.sendPacket( connectionData["ServerIP"], connectionData["ServerPort"], p) def __deleteImageFromInfrastructure(self, data): """ Processes a complete image deletion packet Args: data: a dictionary containing the incoming packet's data Returns: Nothing """ errorDescription = None if (self.__commandsDBConnector.isBeingEdited(data["ImageID"])): errorDescription = ERROR_DESC_T.CLSRVR_LOCKED_IMAGE elif (self.__commandsDBConnector.isBeingDeleted(data["ImageID"])): errorDescription = ERROR_DESC_T.CLSRVR_DELETED_IMAGE elif (self.__commandsDBConnector.getImageVMFamilyID( data["ImageID"]) == None): errorDescription = ERROR_DESC_T.CLSRVR_UNKNOWN_IMAGE if (errorDescription != None): p = self.__packetHandler.createErrorPacket( PACKET_T.DELETE_IMAGE_FROM_INFRASTRUCTURE_ERROR, errorDescription, data["CommandID"]) self.__networkManager.sendPacket('', self.__listenningPort, p) else: p = self.__vmServerPacketHandler.createDeleteImagePacket( data["ImageID"], data["CommandID"]) for serverID in self.__commandsDBConnector.getHosts( data["ImageID"], IMAGE_STATE_T.DELETE): serverData = self.__commandsDBConnector.getVMServerConfiguration( serverID) self.__networkManager.sendPacket(serverData["ServerIP"], serverData["ServerPort"], p) self.__commandsDBConnector.changeImageCopiesState( data["ImageID"], IMAGE_STATE_T.DELETE) self.__commandsDBConnector.deleteImageVMFamilyID(data["ImageID"]) self.__commandsDBConnector.addImageDeletionCommand( data["CommandID"], data["ImageID"]) p = self.__imageRepositoryPacketHandler.createDeleteRequestPacket( data["ImageID"]) self.__networkManager.sendPacket(self.__repositoryIP, self.__repositoryPort, p) def __createOrEditImage(self, data): """ Processes an image creation or an image edition incoming packet Args: data: a dictionary containing the incoming packet's data Returns: Nothing """ errorDescription = None if (self.__commandsDBConnector.isBeingEdited(data["ImageID"])): errorDescription = ERROR_DESC_T.CLSRVR_LOCKED_IMAGE elif (self.__commandsDBConnector.isBeingDeleted(data["ImageID"])): errorDescription = ERROR_DESC_T.CLSRVR_DELETED_IMAGE elif (self.__commandsDBConnector.getImageVMFamilyID( data["ImageID"]) == None): errorDescription = ERROR_DESC_T.CLSRVR_UNKNOWN_IMAGE elif (data["packet_type"] == PACKET_T.CREATE_IMAGE): repositoryStatus = self.__commandsDBConnector.getImageRepositoryStatus( self.__repositoryIP, self.__repositoryPort) if (repositoryStatus == None): errorDescription = ERROR_DESC_T.CLSRVR_IR_CONNECTION_ERROR else: imageFeatures = self.__commandsDBConnector.getVMFamilyFeatures( self.__commandsDBConnector.getImageVMFamilyID( data["ImageID"])) required_disk_space = imageFeatures[ "osDiskSize"] + imageFeatures["dataDiskSize"] required_disk_space = self.__averageCompressionRatio * required_disk_space remaining_disk_space = repositoryStatus[ "FreeDiskSpace"] - required_disk_space if (remaining_disk_space < 0): errorDescription = ERROR_DESC_T.CLSRVR_IR_NO_DISK_SPACE if (errorDescription != None): if (data["packet_type"] == PACKET_T.CREATE_IMAGE): packet_type = PACKET_T.IMAGE_CREATION_ERROR else: packet_type = PACKET_T.IMAGE_EDITION_ERROR p = self.__packetHandler.createErrorPacket(packet_type, errorDescription, data["CommandID"]) self.__networkManager.sendPacket('', self.__listenningPort, p) return (serverID, errorDescription) = self.__loadBalancer.assignVMServer( data["ImageID"], MODE_T.CREATE_OR_EDIT_IMAGE) if (errorDescription != None): if (data["packet_type"] == PACKET_T.CREATE_IMAGE): packet_type = PACKET_T.IMAGE_CREATION_ERROR else: packet_type = PACKET_T.IMAGE_EDITION_ERROR p = self.__packetHandler.createErrorPacket(packet_type, errorDescription, data["CommandID"]) self.__networkManager.sendPacket('', self.__listenningPort, p) return if (data["packet_type"] == PACKET_T.CREATE_IMAGE): self.__commandsDBConnector.registerNewImageVMFamily( data["CommandID"], self.__commandsDBConnector.getImageVMFamilyID(data["ImageID"])) modify = False else: self.__commandsDBConnector.addImageEditionCommand( data["CommandID"], data["ImageID"]) modify = True familyID = self.__commandsDBConnector.getImageVMFamilyID( data["ImageID"]) familyFeatures = self.__commandsDBConnector.getVMFamilyFeatures( familyID) zipFileAllocatedSpace = self.__averageCompressionRatio * ( familyFeatures["osDiskSize"] + familyFeatures["dataDiskSize"]) self.__commandsDBConnector.allocateVMServerResources( data["CommandID"], serverID, familyFeatures["RAMSize"], familyFeatures["osDiskSize"] + familyFeatures["dataDiskSize"], zipFileAllocatedSpace, familyFeatures["vCPUs"], 1) self.__commandsDBConnector.allocateImageRepositoryResources( self.__repositoryIP, self.__repositoryPort, data["CommandID"], zipFileAllocatedSpace) connectionData = self.__commandsDBConnector.getVMServerConfiguration( serverID) p = self.__vmServerPacketHandler.createImageEditionPacket( self.__repositoryIP, self.__repositoryPort, data["ImageID"], modify, data["CommandID"], data["OwnerID"]) self.__networkManager.sendPacket(connectionData["ServerIP"], connectionData["ServerPort"], p) self.__commandsDBConnector.registerActiveVMLocation( data["CommandID"], serverID) def __deployOrDeleteImage(self, data): """ Processes an image deployment or an image deletion incoming packet Args: data: a dictionary containing the incoming packet's data Returns: Nothing """ serverNameOrIPAddress = data["ServerNameOrIPAddress"] serverID = self.__commandsDBConnector.getVMServerID( serverNameOrIPAddress) serverData = self.__commandsDBConnector.getVMServerConfiguration( serverID) errorDescription = None if (self.__commandsDBConnector.isBeingEdited(data["ImageID"])): errorDescription = ERROR_DESC_T.CLSRVR_LOCKED_IMAGE elif (self.__commandsDBConnector.isBeingDeleted(data["ImageID"])): errorDescription = ERROR_DESC_T.CLSRVR_DELETED_IMAGE elif (self.__commandsDBConnector.getImageVMFamilyID( data["ImageID"]) == None): errorDescription = ERROR_DESC_T.CLSRVR_UNKNOWN_IMAGE elif (serverID == None): errorDescription = ERROR_DESC_T.CLSRVR_UNKNOWN_VMSRVR elif (serverData["ServerStatus"] != SERVER_STATE_T.READY): errorDescription = ERROR_DESC_T.CLSRVR_VMSRVR_NOT_READY elif (data["packet_type"] == PACKET_T.DEPLOY_IMAGE and self.__commandsDBConnector.hostsImage(serverID, data["ImageID"]))\ or (data["packet_type"] == PACKET_T.DELETE_IMAGE_FROM_SERVER and not self.__commandsDBConnector.hostsImage(serverID, data["ImageID"])): if (data["packet_type"] == PACKET_T.DEPLOY_IMAGE): errorDescription = ERROR_DESC_T.CLSRVR_IMAGE_HOSTED_ON_VMSRVR else: errorDescription = ERROR_DESC_T.CLSRVR_IMAGE_NOT_HOSTED_ON_VMSRVR elif (data["packet_type"] == PACKET_T.DEPLOY_IMAGE): free_disk_space = self.__commandsDBConnector.getVMServerStatistics( serverID)["FreeStorageSpace"] familyID = self.__commandsDBConnector.getImageVMFamilyID( data["ImageID"]) familyFeatures = self.__commandsDBConnector.getVMFamilyFeatures( familyID) required_disk_space = familyFeatures[ "osDiskSize"] + familyFeatures["dataDiskSize"] if (free_disk_space < required_disk_space): errorDescription = ERROR_DESC_T.CLSRVR_VMSRVR_NO_DISK_SPACE if (errorDescription != None): if (data["packet_type"] == PACKET_T.DEPLOY_IMAGE): error_type = PACKET_T.IMAGE_DEPLOYMENT_ERROR else: error_type = PACKET_T.DELETE_IMAGE_FROM_SERVER_ERROR p = self.__packetHandler.createErrorPacket(error_type, errorDescription, data["CommandID"]) self.__networkManager.sendPacket('', self.__listenningPort, p) return if (data["packet_type"] == PACKET_T.DEPLOY_IMAGE): familyID = self.__commandsDBConnector.getImageVMFamilyID( data["ImageID"]) familyFeatures = self.__commandsDBConnector.getVMFamilyFeatures( familyID) self.__commandsDBConnector.allocateVMServerResources( data["CommandID"], serverID, 0, familyFeatures["osDiskSize"] + familyFeatures["dataDiskSize"], 0, 0, 0) p = self.__vmServerPacketHandler.createImageDeploymentPacket( self.__repositoryIP, self.__repositoryPort, data["ImageID"], data["CommandID"]) else: p = self.__vmServerPacketHandler.createDeleteImagePacket( data["ImageID"], data["CommandID"]) self.__networkManager.sendPacket(serverData["ServerIP"], serverData["ServerPort"], p) def __sendRepositoryStatusData(self): """ Processes an image repository status request packet Args: data: a dictionary containing the incoming packet's data Returns: Nothing """ repositoryStatus = self.__commandsDBConnector.getImageRepositoryStatus( self.__repositoryIP, self.__repositoryPort) p = self.__packetHandler.createRepositoryStatusPacket( repositoryStatus["FreeDiskSpace"], repositoryStatus["AvailableDiskSpace"], repositoryStatus["ConnectionStatus"]) self.__networkManager.sendPacket('', self.__listenningPort, p) def __unregisterOrShutdownVMServer(self, data): """ Unregisters or shuts down a virtual machine server Args: data: a dictionary containing the incoming packet's data Returns: Nothing """ key = data["ServerNameOrIPAddress"] haltServer = data["Halt"] unregister = data["Unregister"] if data.has_key("CommandID"): useCommandID = True commandID = data["CommandID"] else: useCommandID = False commandID = "" serverID = self.__commandsDBConnector.getVMServerID(key) if (serverID == None): if (unregister): packet_type = PACKET_T.VM_SERVER_UNREGISTRATION_ERROR else: packet_type = PACKET_T.VM_SERVER_SHUTDOWN_ERROR p = self.__packetHandler.createErrorPacket( packet_type, key, ERROR_DESC_T.CLSRVR_UNKNOWN_VMSRVR, commandID) self.__networkManager.sendPacket('', self.__listenningPort, p) return serverData = self.__commandsDBConnector.getVMServerConfiguration( serverID) status = serverData["ServerStatus"] if (status == SERVER_STATE_T.READY or status == SERVER_STATE_T.BOOTING): try: connectionReady = self.__networkManager.isConnectionReady( serverData["ServerIP"], serverData["ServerPort"]) except Exception: connectionReady = False if (not connectionReady): if (unregister): packet_type = PACKET_T.VM_SERVER_UNREGISTRATION_ERROR else: packet_type = PACKET_T.VM_SERVER_SHUTDOWN_ERROR p = self.__packetHandler.createErrorPacket( packet_type, ERROR_DESC_T.CLSRVR_VMSRVR_CONNECTION_ERROR, commandID) self.__networkManager.sendPacket('', self.__listenningPort, p) return self.__commandsDBConnector.deleteHostedVMs(serverID) if not haltServer: p = self.__vmServerPacketHandler.createVMServerShutdownPacket() else: p = self.__vmServerPacketHandler.createVMServerHaltPacket() self.__networkManager.sendPacket(serverData["ServerIP"], serverData["ServerPort"], p) self.__networkManager.closeConnection(serverData["ServerIP"], serverData["ServerPort"]) if (unregister): self.__commandsDBConnector.deleteVMServer(key) else: self.__commandsDBConnector.updateVMServerStatus( serverID, SERVER_STATE_T.SHUT_DOWN) if (useCommandID): p = self.__packetHandler.createCommandExecutedPacket(commandID) self.__networkManager.sendPacket('', self.__listenningPort, p) def __sendStatusData(self, queryMethod, packetCreationMethod): """ Processes a status request packet Args: data: a dictionary containing the incoming packet's data Returns: Nothing """ segmentSize = 100 outgoingData = [] serverIDs = self.__commandsDBConnector.getVMServerIDs() if (len(serverIDs) == 0): segmentCounter = 0 segmentNumber = 0 sendLastSegment = True else: segmentCounter = 1 segmentNumber = (len(serverIDs) / segmentSize) if (len(serverIDs) % segmentSize != 0): segmentNumber += 1 sendLastSegment = True else: sendLastSegment = False for serverID in serverIDs: row = queryMethod(serverID) if (row == None): break if (isinstance(row, dict)): outgoingData.append(row) else: outgoingData += row if (len(outgoingData) >= segmentSize): packet = packetCreationMethod(segmentCounter, segmentNumber, outgoingData) self.__networkManager.sendPacket('', self.__listenningPort, packet) outgoingData = [] segmentCounter += 1 if (sendLastSegment): packet = packetCreationMethod(segmentCounter, segmentNumber, outgoingData) self.__networkManager.sendPacket('', self.__listenningPort, packet) def __doImmediateShutdown(self, data): """ Processes a halt packet Args: data: a dictionary containing the incoming packet's data Returns: Nothing """ p = self.__imageRepositoryPacketHandler.createHaltPacket() self.__networkManager.sendPacket(self.__repositoryIP, self.__repositoryPort, p) self.__networkManager.closeConnection(self.__repositoryIP, self.__repositoryPort) vmServersConnectionData = self.__commandsDBConnector.getActiveVMServersConnectionData( ) if (vmServersConnectionData != None): args = dict() args["Halt"] = data["HaltVMServers"] args["Unregister"] = False for connectionData in vmServersConnectionData: args["ServerNameOrIPAddress"] = connectionData["ServerIP"] self.__unregisterOrShutdownVMServer(args) self.__finished = True def __requestVNCConnectionData(self): """ Processes a VNC connection data request packet Args: data: a dictionary containing the incoming packet's data Returns: Nothing """ p = self.__vmServerPacketHandler.createVMServerDataRequestPacket( VMSRVR_PACKET_T.QUERY_ACTIVE_VM_DATA) connectionData = self.__commandsDBConnector.getActiveVMServersConnectionData( ) for cd in connectionData: errorMessage = self.__networkManager.sendPacket( cd["ServerIP"], cd["ServerPort"], p) NetworkManager.printConnectionWarningIfNecessary( cd["ServerIP"], cd["ServerPort"], "VNC connection data request", errorMessage) def __destroyOrRebootDomain(self, data, reboot): """ Processes a domain destruction or a domain reboot packet Args: data: a dictionary containing the incoming packet's data Returns: Nothing """ serverID = self.__commandsDBConnector.getActiveVMHostID( data["DomainID"]) if (serverID == None): if (reboot): packet_type = PACKET_T.DOMAIN_REBOOT_ERROR else: packet_type = PACKET_T.DOMAIN_DESTRUCTION_ERROR packet = self.__packetHandler.createErrorPacket( packet_type, ERROR_DESC_T.CLSRVR_DOMAIN_NOT_REGISTERED, data["CommandID"]) self.__networkManager.sendPacket('', self.__listenningPort, packet) return connectionData = self.__commandsDBConnector.getVMServerConfiguration( serverID) if (reboot): packet = self.__vmServerPacketHandler.createVMRebootPacket( data["DomainID"]) else: packet = self.__vmServerPacketHandler.createVMShutdownPacket( data["DomainID"]) errorMessage = self.__networkManager.sendPacket( connectionData["ServerIP"], connectionData["ServerPort"], packet) if (errorMessage != None): if (reboot): packet_type = PACKET_T.DOMAIN_REBOOT_ERROR else: packet_type = PACKET_T.DOMAIN_DESTRUCTION_ERROR packet = self.__packetHandler.createErrorPacket( packet_type, ERROR_DESC_T.CLSRVR_VMSRVR_CONNECTION_LOST, data["CommandID"]) self.__networkManager.sendPacket('', self.__listenningPort, packet) else: if (not reboot): self.__commandsDBConnector.deleteActiveVMLocation( data["CommandID"]) packet = self.__packetHandler.createCommandExecutedPacket( data["CommandID"]) self.__networkManager.sendPacket('', self.__listenningPort, packet) def __changeVMServerConfiguration(self, data): """ Processes a virtual machine server configuration change packet Args: data: a dictionary containing the incoming packet's data Returns: Nothing """ serverID = self.__commandsDBConnector.getVMServerID( data["ServerNameOrIPAddress"]) if (serverID == None): packet = self.__packetHandler.createErrorPacket( PACKET_T.VM_SERVER_CONFIGURATION_CHANGE_ERROR, ERROR_DESC_T.CLSRVR_UNKNOWN_VMSRVR, data["CommandID"]) self.__networkManager.sendPacket('', self.__listenningPort, packet) return status = self.__commandsDBConnector.getVMServerConfiguration( serverID)["ServerStatus"] if (status == SERVER_STATE_T.BOOTING or status == SERVER_STATE_T.READY): packet = self.__packetHandler.createErrorPacket( PACKET_T.VM_SERVER_CONFIGURATION_CHANGE_ERROR, ERROR_DESC_T.CLSRVR_ACTIVE_VMSRVR, data["CommandID"]) self.__networkManager.sendPacket('', self.__listenningPort, packet) return try: self.__commandsDBConnector.setServerBasicData( serverID, data["NewVMServerName"], SERVER_STATE_T.SHUT_DOWN, data["NewVMServerIPAddress"], data["NewVMServerPort"], data["NewImageEditionBehavior"]) packet = self.__packetHandler.createCommandExecutedPacket( data["CommandID"]) except Exception: packet = self.__packetHandler.createErrorPacket( PACKET_T.VM_SERVER_CONFIGURATION_CHANGE_ERROR, ERROR_DESC_T.CLSRVR_VMSRVR_IDS_IN_USE, data["CommandID"]) self.__networkManager.sendPacket('', self.__listenningPort, packet) def hasFinished(self): """ Indicates if a halt packet was received or not Args: None Returns: True if a halt packet was received, and False if it wasn't """ return self.__finished
class EndpointPacketReactor(object): """ These objects process the packets sent from the cluster endpoint """ def __init__(self, dbConnector, networkManager, vmServerPacketHandler, clusterServerPacketHandler, imageRepositoryPacketHandler, vmServerCallback, listenningPort, repositoryIP, repositoryPort, loadBalancerSettings, averageCompressionRatio, useSSL): """ Initializes the reactor's state Args: dbConnector: a cluster server database connector networkManager: the network manager to use vmServerPacketHandler: the virtual machine server packet handler clusterServerPacketHandler: the cluster server packet handler imageRepositoryPacketHandler: the image repository packet handler vmServerCallback: the virtual machine server packet reactor listenningPort: the control connection's listenning port repositoryIP: the image repository's IP address repositoryPort: the image repository's port loadBalancerSettings: the load balancing algorithm settings averageCompressionRatio: the compression algorithm's average compression ratio useSSL: indicates if the network connections use SSL encryption or not """ self.__commandsDBConnector = dbConnector self.__networkManager = networkManager self.__vmServerPacketHandler = vmServerPacketHandler self.__packetHandler = clusterServerPacketHandler self.__imageRepositoryPacketHandler = imageRepositoryPacketHandler self.__loadBalancer = PenaltyBasedLoadBalancer(self.__commandsDBConnector, loadBalancerSettings[1], loadBalancerSettings[2], loadBalancerSettings[3], loadBalancerSettings[4], loadBalancerSettings[5]) self.__averageCompressionRatio = averageCompressionRatio self.__vmServerCallback = vmServerCallback self.__listenningPort = listenningPort self.__repositoryIP = repositoryIP self.__repositoryPort = repositoryPort self.__finished = False self.__useSSL = useSSL def processClusterEndpointIncomingPacket(self, packet): """ Processes a packet sent from the cluster endpoint Args: packet: the packet to process Returns: Nothing """ data = self.__packetHandler.readPacket(packet) if (data["packet_type"] == PACKET_T.REGISTER_VM_SERVER) : self.__registerVMServer(data) elif (data["packet_type"] == PACKET_T.QUERY_VM_SERVERS_STATUS) : self.__sendStatusData(self.__commandsDBConnector.getVMServerConfiguration, self.__packetHandler.createVMServerStatusPacket) elif (data["packet_type"] == PACKET_T.UNREGISTER_OR_SHUTDOWN_VM_SERVER) : self.__unregisterOrShutdownVMServer(data) elif (data["packet_type"] == PACKET_T.BOOTUP_VM_SERVER) : self.__bootVMServer(data) elif (data["packet_type"] == PACKET_T.VM_BOOT_REQUEST): self.__bootVM(data) elif (data["packet_type"] == PACKET_T.HALT) : self.__doImmediateShutdown(data) elif (data["packet_type"] == PACKET_T.QUERY_VM_DISTRIBUTION) : self.__sendStatusData(self.__commandsDBConnector.getHostedImages, self.__packetHandler.createVMDistributionPacket) elif (data["packet_type"] == PACKET_T.QUERY_ACTIVE_VM_VNC_DATA) : self.__requestVNCConnectionData() elif (data["packet_type"] == PACKET_T.DOMAIN_DESTRUCTION) : self.__destroyOrRebootDomain(data, False) elif (data["packet_type"] == PACKET_T.DOMAIN_REBOOT) : self.__destroyOrRebootDomain(data, True) elif (data["packet_type"] == PACKET_T.VM_SERVER_CONFIGURATION_CHANGE): self.__changeVMServerConfiguration(data) elif (data["packet_type"] == PACKET_T.QUERY_REPOSITORY_STATUS): self.__sendRepositoryStatusData() elif (data["packet_type"] == PACKET_T.DEPLOY_IMAGE or data["packet_type"] == PACKET_T.DELETE_IMAGE_FROM_SERVER): self.__deployOrDeleteImage(data) elif (data["packet_type"] == PACKET_T.CREATE_IMAGE or data["packet_type"] == PACKET_T.EDIT_IMAGE): self.__createOrEditImage(data) elif (data["packet_type"] == PACKET_T.DELETE_IMAGE_FROM_INFRASTRUCTURE): self.__deleteImageFromInfrastructure(data) elif (data["packet_type"] == PACKET_T.AUTO_DEPLOY): self.__auto_deploy_image(data) elif (data["packet_type"] == PACKET_T.QUERY_VM_SERVERS_RESOURCE_USAGE): self.__sendStatusData(self.__commandsDBConnector.getVMServerStatisticsToSend, self.__packetHandler.createVMServerResourceUsagePacket) def __registerVMServer(self, data): """ Processes a virtual machine server registration packet Args: data: a dictionary containing the incoming packet's data Returns: Nothing """ try : # Comprobar si la IP y el nombre del servidor ya están en uso server_id = self.__commandsDBConnector.getVMServerID(data["VMServerIP"]) if (server_id != None) : raise Exception("The IP address " + data["VMServerIP"] + " is assigned to another VM server") server_id = self.__commandsDBConnector.getVMServerID(data["VMServerName"]) if (server_id != None) : raise Exception("The name " + data["VMServerName"] + " is assigned to another VM server") # Establecer la conexión self.__networkManager.connectTo(data["VMServerIP"], data["VMServerPort"], 20, self.__vmServerCallback, self.__useSSL, True) while not self.__networkManager.isConnectionReady(data["VMServerIP"], data["VMServerPort"]) : sleep(0.1) # Registrar el nuevo servidor y pedirle su estado self.__commandsDBConnector.registerVMServer(data["VMServerName"], data["VMServerIP"], data["VMServerPort"], data["IsEditionServer"]) # Indicar al endpoint de la web que el comando se ha ejecutado con éxito p = self.__packetHandler.createCommandExecutedPacket(data["CommandID"]) except Exception: p = self.__packetHandler.createErrorPacket(PACKET_T.VM_SERVER_REGISTRATION_ERROR, ERROR_DESC_T.CLSRVR_VMSRVR_CONNECTION_ERROR, data["CommandID"]) self.__networkManager.sendPacket('', self.__listenningPort, p) def __bootVMServer(self, data): """ Processes a virtual machine server boot packet Args: data: a dictionary containing the incoming packet's data Returns: Nothing """ try : serverNameOrIPAddress = data["ServerNameOrIPAddress"] serverId = self.__commandsDBConnector.getVMServerID(serverNameOrIPAddress) if (serverId == None) : p = self.__packetHandler.createErrorPacket(PACKET_T.VM_SERVER_BOOTUP_ERROR, ERROR_DESC_T.CLSRVR_UNKNOWN_VMSRVR, data["CommandID"]) else : serverData = self.__commandsDBConnector.getVMServerConfiguration(serverId) if (serverData["ServerStatus"] == SERVER_STATE_T.SHUT_DOWN or serverData["ServerStatus"] == SERVER_STATE_T.CONNECTION_TIMED_OUT) : self.__networkManager.connectTo(serverData["ServerIP"], serverData["ServerPort"], 20, self.__vmServerCallback, self.__useSSL, True) while not self.__networkManager.isConnectionReady(serverData["ServerIP"], serverData["ServerPort"]) : sleep(0.1) self.__commandsDBConnector.updateVMServerStatus(serverId, SERVER_STATE_T.BOOTING) imagesToDeploy = self.__commandsDBConnector.getHostedImagesInState(serverId, IMAGE_STATE_T.DEPLOY) for imageID in imagesToDeploy : familyID = self.__commandsDBConnector.getImageVMFamilyID(imageID) familyFeatures = self.__commandsDBConnector.getVMFamilyFeatures(familyID) p = self.__vmServerPacketHandler.createImageDeploymentPacket(self.__repositoryIP, self.__repositoryPort, imageID, self.__commandsDBConnector.getImageEditionCommandID(imageID)) self.__commandsDBConnector.allocateVMServerResources(data["CommandID"], serverId, 0, familyFeatures["osDiskSize"] + familyFeatures["dataDiskSize"], 0, 0, 1) self.__networkManager.sendPacket(serverData["ServerIP"], serverData["ServerPort"], p) imagesToDelete = self.__commandsDBConnector.getHostedImagesInState(serverId, IMAGE_STATE_T.DELETE) for imageID in imagesToDelete : p = self.__vmServerPacketHandler.createDeleteImagePacket(imageID, self.__commandsDBConnector.getImageDeletionCommandID(imageID)) self.__networkManager.sendPacket(serverData["ServerIP"], serverData["ServerPort"], p) p = self.__packetHandler.createCommandExecutedPacket(data["CommandID"]) except Exception: p = self.__packetHandler.createErrorPacket(PACKET_T.VM_SERVER_BOOTUP_ERROR, ERROR_DESC_T.CLSRVR_VMSRVR_CONNECTION_ERROR, data["CommandID"]) self.__networkManager.sendPacket('', self.__listenningPort, p) def __bootVM(self, data): """ Processes a virtual machine server boot packet Args: data: a dictionary containing the incoming packet's data Returns: Nothing """ vmID = data["VMID"] userID = data["UserID"] (serverID, errorDescription) = self.__loadBalancer.assignVMServer(vmID, MODE_T.BOOT_DOMAIN) if (errorDescription != None) : p = self.__packetHandler.createErrorPacket(PACKET_T.VM_BOOT_FAILURE, errorDescription, data["CommandID"]) self.__networkManager.sendPacket('', self.__listenningPort, p) else : familyID = self.__commandsDBConnector.getImageVMFamilyID(vmID) familyFeatures = self.__commandsDBConnector.getVMFamilyFeatures(familyID) self.__commandsDBConnector.allocateVMServerResources(data["CommandID"], serverID, familyFeatures["RAMSize"], 0, familyFeatures["dataDiskSize"], familyFeatures["vCPUs"], 1) p = self.__vmServerPacketHandler.createVMBootPacket(vmID, userID, data["CommandID"]) serverData = self.__commandsDBConnector.getVMServerConfiguration(serverID) error = self.__networkManager.sendPacket(serverData["ServerIP"], serverData["ServerPort"], p) if (error != None) : p = self.__packetHandler.createErrorPacket(PACKET_T.VM_BOOT_FAILURE, ERROR_DESC_T.CLSRVR_VMSRVR_CONNECTION_LOST, data["CommandID"]) self.__networkManager.sendPacket('', self.__listenningPort, p) self.__commandsDBConnector.freeVMServerResources(data["CommandID"], True) return self.__commandsDBConnector.registerActiveVMLocation(data["CommandID"], serverID) self.__commandsDBConnector.registerVMBootCommand(data["CommandID"], data["VMID"]) def __auto_deploy_image(self, data): """ Processes an image auto-deployment packet Args: data: a dictionary containing the incoming packet's data Returns: Nothing """ if (data["Instances"] == 0 or data["Instances"] < -1) : p = self.__packetHandler.createCommandExecutedPacket(data["CommandID"]) self.__networkManager.sendPacket('', self.__listenningPort, p) return familyID = self.__commandsDBConnector.getImageVMFamilyID(data["ImageID"]) if (familyID == None) : p = self.__packetHandler.createErrorPacket(PACKET_T.AUTO_DEPLOY_ERROR, ERROR_DESC_T.CLSRVR_UNKNOWN_IMAGE, data["CommandID"]) self.__networkManager.sendPacket('', self.__listenningPort, p) return familyFeatures = self.__commandsDBConnector.getVMFamilyFeatures(familyID) if (data["Instances"] == -1) : if (not self.__commandsDBConnector.isBeingDeleted(data["ImageID"])) : self.__commandsDBConnector.changeImageCopiesState(data["ImageID"], IMAGE_STATE_T.DEPLOY) serverIDs = self.__commandsDBConnector.getHosts(data["ImageID"], IMAGE_STATE_T.DEPLOY) if (serverIDs != []) : self.__commandsDBConnector.addImageEditionCommand(data["CommandID"], data["ImageID"]) p = self.__vmServerPacketHandler.createImageDeploymentPacket(self.__repositoryIP, self.__repositoryPort, data["ImageID"], data["CommandID"]) for serverID in serverIDs : self.__commandsDBConnector.allocateVMServerResources(data["CommandID"], serverID, 0, familyFeatures["osDiskSize"] + familyFeatures["dataDiskSize"], 0, 0, 1) connectionData = self.__commandsDBConnector.getVMServerConfiguration(serverID) self.__networkManager.sendPacket(connectionData["ServerIP"], connectionData["ServerPort"], p) else : if (not self.__commandsDBConnector.isThereSomeImageCopyInState(data["ImageID"], IMAGE_STATE_T.EDITED)) : p = self.__packetHandler.createCommandExecutedPacket(data["CommandID"]) self.__networkManager.sendPacket('', self.__listenningPort, p) else : p = self.__packetHandler.createErrorPacket(PACKET_T.AUTO_DEPLOY_ERROR, ERROR_DESC_T.CLSRVR_NOT_EDITED_IMAGE, data["CommandID"]) self.__networkManager.sendPacket('', self.__listenningPort, p) elif (data["Instances"] > 0) : if (self.__commandsDBConnector.isAffectedByAutoDeploymentCommand(data["ImageID"])) : p = self.__packetHandler.createErrorPacket(PACKET_T.AUTO_DEPLOY_ERROR, ERROR_DESC_T.CLSRVR_AUTODEPLOYED, data["CommandID"]) self.__networkManager.sendPacket('', self.__listenningPort, p) return output = self.__loadBalancer.assignVMServer(data["ImageID"], MODE_T.DEPLOY_IMAGE) if (output[1] != None) : p = self.__packetHandler.createErrorPacket(PACKET_T.AUTO_DEPLOY_ERROR, output[1], data["CommandID"]) self.__networkManager.sendPacket('', self.__listenningPort, p) else : if (output[2] < data["Instances"]) : p = self.__packetHandler.createErrorPacket(PACKET_T.AUTO_DEPLOY_ERROR, ERROR_DESC_T.CLSRVR_AUTOD_TOO_MANY_INSTANCES, data["CommandID"]) self.__networkManager.sendPacket('', self.__listenningPort, p) else : servers = [] deployed_copies = 0 i = 0 while (deployed_copies < data["Instances"]) : servers.append(output[i][0][0]) deployed_copies += output[i][0][1] i += 1 self.__commandsDBConnector.addAutoDeploymentCommand(data["CommandID"], data["ImageID"], len(servers)) p = self.__vmServerPacketHandler.createImageDeploymentPacket(self.__repositoryIP, self.__repositoryPort, data["ImageID"], data["CommandID"]) for serverID in servers: self.__commandsDBConnector.allocateVMServerResources(data["CommandID"], serverID, 0, familyFeatures["osDiskSize"] + familyFeatures["dataDiskSize"], 0, 0, 1) connectionData = self.__commandsDBConnector.getVMServerConfiguration(serverID) self.__networkManager.sendPacket(connectionData["ServerIP"], connectionData["ServerPort"], p) def __deleteImageFromInfrastructure(self, data): """ Processes a complete image deletion packet Args: data: a dictionary containing the incoming packet's data Returns: Nothing """ errorDescription = None if (self.__commandsDBConnector.isBeingEdited(data["ImageID"])) : errorDescription = ERROR_DESC_T.CLSRVR_LOCKED_IMAGE elif (self.__commandsDBConnector.isBeingDeleted(data["ImageID"])) : errorDescription = ERROR_DESC_T.CLSRVR_DELETED_IMAGE elif (self.__commandsDBConnector.getImageVMFamilyID(data["ImageID"]) == None) : errorDescription = ERROR_DESC_T.CLSRVR_UNKNOWN_IMAGE if (errorDescription != None) : p = self.__packetHandler.createErrorPacket(PACKET_T.DELETE_IMAGE_FROM_INFRASTRUCTURE_ERROR, errorDescription, data["CommandID"]) self.__networkManager.sendPacket('', self.__listenningPort, p) else : p = self.__vmServerPacketHandler.createDeleteImagePacket(data["ImageID"], data["CommandID"]) for serverID in self.__commandsDBConnector.getHosts(data["ImageID"], IMAGE_STATE_T.DELETE) : serverData = self.__commandsDBConnector.getVMServerConfiguration(serverID) self.__networkManager.sendPacket(serverData["ServerIP"], serverData["ServerPort"], p) self.__commandsDBConnector.changeImageCopiesState(data["ImageID"], IMAGE_STATE_T.DELETE) self.__commandsDBConnector.deleteImageVMFamilyID(data["ImageID"]) self.__commandsDBConnector.addImageDeletionCommand(data["CommandID"], data["ImageID"]) p = self.__imageRepositoryPacketHandler.createDeleteRequestPacket(data["ImageID"]) self.__networkManager.sendPacket(self.__repositoryIP, self.__repositoryPort, p) def __createOrEditImage(self, data): """ Processes an image creation or an image edition incoming packet Args: data: a dictionary containing the incoming packet's data Returns: Nothing """ errorDescription = None if (self.__commandsDBConnector.isBeingEdited(data["ImageID"])) : errorDescription = ERROR_DESC_T.CLSRVR_LOCKED_IMAGE elif (self.__commandsDBConnector.isBeingDeleted(data["ImageID"])) : errorDescription = ERROR_DESC_T.CLSRVR_DELETED_IMAGE elif (self.__commandsDBConnector.getImageVMFamilyID(data["ImageID"]) == None) : errorDescription = ERROR_DESC_T.CLSRVR_UNKNOWN_IMAGE elif (data["packet_type"] == PACKET_T.CREATE_IMAGE): repositoryStatus = self.__commandsDBConnector.getImageRepositoryStatus(self.__repositoryIP, self.__repositoryPort) if (repositoryStatus == None) : errorDescription = ERROR_DESC_T.CLSRVR_IR_CONNECTION_ERROR else : imageFeatures = self.__commandsDBConnector.getVMFamilyFeatures(self.__commandsDBConnector.getImageVMFamilyID(data["ImageID"])) required_disk_space = imageFeatures["osDiskSize"] + imageFeatures["dataDiskSize"] required_disk_space = self.__averageCompressionRatio * required_disk_space remaining_disk_space = repositoryStatus["FreeDiskSpace"] - required_disk_space if (remaining_disk_space < 0) : errorDescription = ERROR_DESC_T.CLSRVR_IR_NO_DISK_SPACE if (errorDescription != None) : if (data["packet_type"] == PACKET_T.CREATE_IMAGE) : packet_type = PACKET_T.IMAGE_CREATION_ERROR else : packet_type = PACKET_T.IMAGE_EDITION_ERROR p = self.__packetHandler.createErrorPacket(packet_type, errorDescription, data["CommandID"]) self.__networkManager.sendPacket('', self.__listenningPort, p) return (serverID, errorDescription) = self.__loadBalancer.assignVMServer(data["ImageID"], MODE_T.CREATE_OR_EDIT_IMAGE) if (errorDescription != None) : if (data["packet_type"] == PACKET_T.CREATE_IMAGE) : packet_type = PACKET_T.IMAGE_CREATION_ERROR else : packet_type = PACKET_T.IMAGE_EDITION_ERROR p = self.__packetHandler.createErrorPacket(packet_type, errorDescription, data["CommandID"]) self.__networkManager.sendPacket('', self.__listenningPort, p) return if (data["packet_type"] == PACKET_T.CREATE_IMAGE) : self.__commandsDBConnector.registerNewImageVMFamily(data["CommandID"], self.__commandsDBConnector.getImageVMFamilyID(data["ImageID"])) modify = False else : self.__commandsDBConnector.addImageEditionCommand(data["CommandID"], data["ImageID"]) modify = True familyID = self.__commandsDBConnector.getImageVMFamilyID(data["ImageID"]) familyFeatures = self.__commandsDBConnector.getVMFamilyFeatures(familyID) zipFileAllocatedSpace = self.__averageCompressionRatio * (familyFeatures["osDiskSize"] + familyFeatures["dataDiskSize"]) self.__commandsDBConnector.allocateVMServerResources(data["CommandID"], serverID, familyFeatures["RAMSize"], familyFeatures["osDiskSize"] + familyFeatures["dataDiskSize"], zipFileAllocatedSpace, familyFeatures["vCPUs"], 1) self.__commandsDBConnector.allocateImageRepositoryResources(self.__repositoryIP, self.__repositoryPort, data["CommandID"], zipFileAllocatedSpace) connectionData = self.__commandsDBConnector.getVMServerConfiguration(serverID) p = self.__vmServerPacketHandler.createImageEditionPacket(self.__repositoryIP, self.__repositoryPort, data["ImageID"], modify, data["CommandID"], data["OwnerID"]) self.__networkManager.sendPacket(connectionData["ServerIP"], connectionData["ServerPort"], p) self.__commandsDBConnector.registerActiveVMLocation(data["CommandID"], serverID) def __deployOrDeleteImage(self, data): """ Processes an image deployment or an image deletion incoming packet Args: data: a dictionary containing the incoming packet's data Returns: Nothing """ serverNameOrIPAddress = data["ServerNameOrIPAddress"] serverID = self.__commandsDBConnector.getVMServerID(serverNameOrIPAddress) serverData = self.__commandsDBConnector.getVMServerConfiguration(serverID) errorDescription = None if (self.__commandsDBConnector.isBeingEdited(data["ImageID"])) : errorDescription = ERROR_DESC_T.CLSRVR_LOCKED_IMAGE elif (self.__commandsDBConnector.isBeingDeleted(data["ImageID"])): errorDescription = ERROR_DESC_T.CLSRVR_DELETED_IMAGE elif (self.__commandsDBConnector.getImageVMFamilyID(data["ImageID"]) == None) : errorDescription = ERROR_DESC_T.CLSRVR_UNKNOWN_IMAGE elif (serverID == None) : errorDescription = ERROR_DESC_T.CLSRVR_UNKNOWN_VMSRVR elif (serverData["ServerStatus"] != SERVER_STATE_T.READY): errorDescription = ERROR_DESC_T.CLSRVR_VMSRVR_NOT_READY elif (data["packet_type"] == PACKET_T.DEPLOY_IMAGE and self.__commandsDBConnector.hostsImage(serverID, data["ImageID"]))\ or (data["packet_type"] == PACKET_T.DELETE_IMAGE_FROM_SERVER and not self.__commandsDBConnector.hostsImage(serverID, data["ImageID"])): if (data["packet_type"] == PACKET_T.DEPLOY_IMAGE): errorDescription = ERROR_DESC_T.CLSRVR_IMAGE_HOSTED_ON_VMSRVR else : errorDescription = ERROR_DESC_T.CLSRVR_IMAGE_NOT_HOSTED_ON_VMSRVR elif (data["packet_type"] == PACKET_T.DEPLOY_IMAGE): free_disk_space = self.__commandsDBConnector.getVMServerStatistics(serverID)["FreeStorageSpace"] familyID = self.__commandsDBConnector.getImageVMFamilyID(data["ImageID"]) familyFeatures = self.__commandsDBConnector.getVMFamilyFeatures(familyID) required_disk_space = familyFeatures["osDiskSize"] + familyFeatures["dataDiskSize"] if (free_disk_space < required_disk_space) : errorDescription = ERROR_DESC_T.CLSRVR_VMSRVR_NO_DISK_SPACE if (errorDescription != None) : if (data["packet_type"] == PACKET_T.DEPLOY_IMAGE): error_type = PACKET_T.IMAGE_DEPLOYMENT_ERROR else: error_type = PACKET_T.DELETE_IMAGE_FROM_SERVER_ERROR p = self.__packetHandler.createErrorPacket(error_type, errorDescription, data["CommandID"]) self.__networkManager.sendPacket('', self.__listenningPort, p) return if (data["packet_type"] == PACKET_T.DEPLOY_IMAGE) : familyID = self.__commandsDBConnector.getImageVMFamilyID(data["ImageID"]) familyFeatures = self.__commandsDBConnector.getVMFamilyFeatures(familyID) self.__commandsDBConnector.allocateVMServerResources(data["CommandID"], serverID, 0, familyFeatures["osDiskSize"] + familyFeatures["dataDiskSize"], 0, 0, 0) p = self.__vmServerPacketHandler.createImageDeploymentPacket(self.__repositoryIP, self.__repositoryPort, data["ImageID"], data["CommandID"]) else: p = self.__vmServerPacketHandler.createDeleteImagePacket(data["ImageID"], data["CommandID"]) self.__networkManager.sendPacket(serverData["ServerIP"], serverData["ServerPort"], p) def __sendRepositoryStatusData(self): """ Processes an image repository status request packet Args: data: a dictionary containing the incoming packet's data Returns: Nothing """ repositoryStatus = self.__commandsDBConnector.getImageRepositoryStatus(self.__repositoryIP, self.__repositoryPort) p = self.__packetHandler.createRepositoryStatusPacket(repositoryStatus["FreeDiskSpace"], repositoryStatus["AvailableDiskSpace"], repositoryStatus["ConnectionStatus"]) self.__networkManager.sendPacket('', self.__listenningPort, p) def __unregisterOrShutdownVMServer(self, data): """ Unregisters or shuts down a virtual machine server Args: data: a dictionary containing the incoming packet's data Returns: Nothing """ key = data["ServerNameOrIPAddress"] haltServer = data["Halt"] unregister = data["Unregister"] if data.has_key("CommandID") : useCommandID = True commandID = data["CommandID"] else : useCommandID = False commandID = "" serverID = self.__commandsDBConnector.getVMServerID(key) if (serverID == None) : if (unregister) : packet_type = PACKET_T.VM_SERVER_UNREGISTRATION_ERROR else : packet_type = PACKET_T.VM_SERVER_SHUTDOWN_ERROR p = self.__packetHandler.createErrorPacket(packet_type, key, ERROR_DESC_T.CLSRVR_UNKNOWN_VMSRVR, commandID) self.__networkManager.sendPacket('', self.__listenningPort, p) return serverData = self.__commandsDBConnector.getVMServerConfiguration(serverID) status = serverData["ServerStatus"] if (status == SERVER_STATE_T.READY or status == SERVER_STATE_T.BOOTING) : try : connectionReady = self.__networkManager.isConnectionReady(serverData["ServerIP"], serverData["ServerPort"]) except Exception: connectionReady = False if (not connectionReady) : if (unregister) : packet_type = PACKET_T.VM_SERVER_UNREGISTRATION_ERROR else : packet_type = PACKET_T.VM_SERVER_SHUTDOWN_ERROR p = self.__packetHandler.createErrorPacket(packet_type, ERROR_DESC_T.CLSRVR_VMSRVR_CONNECTION_ERROR, commandID) self.__networkManager.sendPacket('', self.__listenningPort, p) return self.__commandsDBConnector.deleteHostedVMs(serverID) if not haltServer : p = self.__vmServerPacketHandler.createVMServerShutdownPacket() else : p = self.__vmServerPacketHandler.createVMServerHaltPacket() self.__networkManager.sendPacket(serverData["ServerIP"], serverData["ServerPort"], p) self.__networkManager.closeConnection(serverData["ServerIP"], serverData["ServerPort"]) if (unregister) : self.__commandsDBConnector.deleteVMServer(key) else: self.__commandsDBConnector.updateVMServerStatus(serverID, SERVER_STATE_T.SHUT_DOWN) if (useCommandID) : p = self.__packetHandler.createCommandExecutedPacket(commandID) self.__networkManager.sendPacket('', self.__listenningPort, p) def __sendStatusData(self, queryMethod, packetCreationMethod): """ Processes a status request packet Args: data: a dictionary containing the incoming packet's data Returns: Nothing """ segmentSize = 100 outgoingData = [] serverIDs = self.__commandsDBConnector.getVMServerIDs() if (len(serverIDs) == 0) : segmentCounter = 0 segmentNumber = 0 sendLastSegment = True else : segmentCounter = 1 segmentNumber = (len(serverIDs) / segmentSize) if (len(serverIDs) % segmentSize != 0) : segmentNumber += 1 sendLastSegment = True else : sendLastSegment = False for serverID in serverIDs : row = queryMethod(serverID) if (row == None): break if (isinstance(row, dict)) : outgoingData.append(row) else : outgoingData += row if (len(outgoingData) >= segmentSize) : packet = packetCreationMethod(segmentCounter, segmentNumber, outgoingData) self.__networkManager.sendPacket('', self.__listenningPort, packet) outgoingData = [] segmentCounter += 1 if (sendLastSegment) : packet = packetCreationMethod(segmentCounter, segmentNumber, outgoingData) self.__networkManager.sendPacket('', self.__listenningPort, packet) def __doImmediateShutdown(self, data): """ Processes a halt packet Args: data: a dictionary containing the incoming packet's data Returns: Nothing """ p = self.__imageRepositoryPacketHandler.createHaltPacket() self.__networkManager.sendPacket(self.__repositoryIP, self.__repositoryPort, p) self.__networkManager.closeConnection(self.__repositoryIP, self.__repositoryPort) vmServersConnectionData = self.__commandsDBConnector.getActiveVMServersConnectionData() if (vmServersConnectionData != None) : args = dict() args["Halt"] = data["HaltVMServers"] args["Unregister"] = False for connectionData in vmServersConnectionData : args["ServerNameOrIPAddress"] = connectionData["ServerIP"] self.__unregisterOrShutdownVMServer(args) self.__finished = True def __requestVNCConnectionData(self): """ Processes a VNC connection data request packet Args: data: a dictionary containing the incoming packet's data Returns: Nothing """ p = self.__vmServerPacketHandler.createVMServerDataRequestPacket(VMSRVR_PACKET_T.QUERY_ACTIVE_VM_DATA) connectionData = self.__commandsDBConnector.getActiveVMServersConnectionData() for cd in connectionData : errorMessage = self.__networkManager.sendPacket(cd["ServerIP"], cd["ServerPort"], p) NetworkManager.printConnectionWarningIfNecessary(cd["ServerIP"], cd["ServerPort"], "VNC connection data request", errorMessage) def __destroyOrRebootDomain(self, data, reboot): """ Processes a domain destruction or a domain reboot packet Args: data: a dictionary containing the incoming packet's data Returns: Nothing """ serverID = self.__commandsDBConnector.getActiveVMHostID(data["DomainID"]) if (serverID == None) : if (reboot) : packet_type = PACKET_T.DOMAIN_REBOOT_ERROR else: packet_type = PACKET_T.DOMAIN_DESTRUCTION_ERROR packet = self.__packetHandler.createErrorPacket(packet_type, ERROR_DESC_T.CLSRVR_DOMAIN_NOT_REGISTERED, data["CommandID"]) self.__networkManager.sendPacket('', self.__listenningPort, packet) return connectionData = self.__commandsDBConnector.getVMServerConfiguration(serverID) if (reboot) : packet = self.__vmServerPacketHandler.createVMRebootPacket(data["DomainID"]) else : packet = self.__vmServerPacketHandler.createVMShutdownPacket(data["DomainID"]) errorMessage = self.__networkManager.sendPacket(connectionData["ServerIP"], connectionData["ServerPort"], packet) if (errorMessage != None) : if (reboot) : packet_type = PACKET_T.DOMAIN_REBOOT_ERROR else: packet_type = PACKET_T.DOMAIN_DESTRUCTION_ERROR packet = self.__packetHandler.createErrorPacket(packet_type, ERROR_DESC_T.CLSRVR_VMSRVR_CONNECTION_LOST, data["CommandID"]) self.__networkManager.sendPacket('', self.__listenningPort, packet) else : if (not reboot) : self.__commandsDBConnector.deleteActiveVMLocation(data["CommandID"]) packet = self.__packetHandler.createCommandExecutedPacket(data["CommandID"]) self.__networkManager.sendPacket('', self.__listenningPort, packet) def __changeVMServerConfiguration(self, data): """ Processes a virtual machine server configuration change packet Args: data: a dictionary containing the incoming packet's data Returns: Nothing """ serverID = self.__commandsDBConnector.getVMServerID(data["ServerNameOrIPAddress"]) if (serverID == None) : packet = self.__packetHandler.createErrorPacket(PACKET_T.VM_SERVER_CONFIGURATION_CHANGE_ERROR, ERROR_DESC_T.CLSRVR_UNKNOWN_VMSRVR, data["CommandID"]) self.__networkManager.sendPacket('', self.__listenningPort, packet) return status = self.__commandsDBConnector.getVMServerConfiguration(serverID)["ServerStatus"] if (status == SERVER_STATE_T.BOOTING or status == SERVER_STATE_T.READY) : packet = self.__packetHandler.createErrorPacket(PACKET_T.VM_SERVER_CONFIGURATION_CHANGE_ERROR, ERROR_DESC_T.CLSRVR_ACTIVE_VMSRVR, data["CommandID"]) self.__networkManager.sendPacket('', self.__listenningPort, packet) return try : self.__commandsDBConnector.setServerBasicData(serverID, data["NewVMServerName"], SERVER_STATE_T.SHUT_DOWN, data["NewVMServerIPAddress"], data["NewVMServerPort"], data["NewImageEditionBehavior"]) packet = self.__packetHandler.createCommandExecutedPacket(data["CommandID"]) except Exception : packet = self.__packetHandler.createErrorPacket(PACKET_T.VM_SERVER_CONFIGURATION_CHANGE_ERROR, ERROR_DESC_T.CLSRVR_VMSRVR_IDS_IN_USE, data["CommandID"]) self.__networkManager.sendPacket('', self.__listenningPort, packet) def hasFinished(self): """ Indicates if a halt packet was received or not Args: None Returns: True if a halt packet was received, and False if it wasn't """ return self.__finished