def cleanupClients(self): # For each group in the list of clients, find the unavailable address # and remove it. emptyGroups = [] for grp in self.clients.collection(): addresses = self.clients.get(grp) for addr in addresses: try: s = socket.socket(socket.AF_INET, socket.SOCK_STREAM) s.settimeout(5) s.connect(addr) s.close() except: print('Removing inactive client "%s:%d"' % (addr[0], addr[1])) addresses.remove(addr) myConnector = mysql(self.addr[0], 3306) myConnector.connect() myConnector.deleteNodeByIP(addr[0] + ':' + str(addr[1])) myConnector.disconnect() if (len(self.clients.get(grp)) == 0): emptyGroups += [grp] # Any groups with no clients should be removed for grp in emptyGroups: print('Removing empty group "%s"' % grp) del self.clients.collection()[grp]
def registerClient(self, host, group): # send an authorization request to the server. The server should # return a nonce value. ret = self.publishToHost(host, createMessage(cmd='AUTH')) nonce = ret['nonce'] # encrypt the nonce with pre-shared key and send it back to the host. decVal = auth.encrypt(nonce).decode('UTF8') message = createMessage(cmd='SUBSCRIBE', ip=self.addr[0], port=self.addr[1], group=self.group, nonce=decVal) # TODO: What to do with ret? ret = self.publishToHost(host, message) # save the IP of the publisher. self._publisher = host # start a heartbeat for fault tolerance self._heartBeatThread = threading.Thread(target=self.heartBeat) self._heartBeatThread.start() # Insert the ndoe into the database myConnector = mysql(str(host[0]), 3306) myConnector.connect() myConnector.insertNode(self.name, self.addr[0] + ':' + str(self.addr[1]), self.group) myConnector.disconnect()
def registerClient(self, host, group): # send an authorization request to the server. The server should # return a nonce value. ret = self.publishToHost(host, createMessage(cmd='AUTH')) nonce = ret['nonce'] # encrypt the nonce with pre-shared key and send it back to the host. decVal = auth.encrypt(nonce).decode('UTF8') message = createMessage(cmd='SUBSCRIBE', ip=self.addr[0], port=self.addr[1], group=self.group, nonce=decVal) # TODO: What to do with ret? ret = self.publishToHost(host, message) # save the IP of the publisher. self._publisher = host # start a heartbeat for fault tolerance self._heartBeatThread = threading.Thread(target = self.heartBeat) self._heartBeatThread.start() # Insert the ndoe into the database myConnector = mysql(str(host[0]), 3306) myConnector.connect() myConnector.insertNode(self.name, self.addr[0]+':'+str(self.addr[1]), self.group) myConnector.disconnect()
def cleanupClients(self): # For each group in the list of clients, find the unavailable address # and remove it. emptyGroups = [] for grp in self.clients.collection(): addresses = self.clients.get(grp) for addr in addresses: try: s = socket.socket(socket.AF_INET, socket.SOCK_STREAM) s.settimeout(5) s.connect(addr) s.close() except: print('Removing inactive client "%s:%d"' % (addr[0],addr[1])) addresses.remove(addr) myConnector = mysql(self.addr[0], 3306) myConnector.connect() myConnector.deleteNodeByIP(addr[0]+':'+str(addr[1])) myConnector.disconnect() if (len(self.clients.get(grp)) == 0): emptyGroups += [grp] # Any groups with no clients should be removed for grp in emptyGroups: print('Removing empty group "%s"' % grp) del self.clients.collection()[grp]
def destroyAll(data): vmDestructor = subprocess.Popen("./destroyAll.sh", stdout=subprocess.PIPE) out, err = vmDestructor.communicate() if err != "": return 1 publisher = client.publisher[0] myConnector = mysql(publisher, 3306) myConnector.connect() myConnector.deleteInstance(domain) myConnector.disconnect() return 0
def destroyAll(data): vmDestructor = subprocess.Popen('./destroyAll.sh', \ stdout=subprocess.PIPE) out, err = vmDestructor.communicate() if (err != ""): return 1 publisher = client.publisher[0] myConnector = mysql(publisher, 3306) myConnector.connect() myConnector.deleteInstance(domain) myConnector.disconnect() return 0
def instantiate(data): # Get posiotional arguments name = data["vm"] username = data["user"] # Get the IP of the publisher publisher = client.publisher[0] # Get image information myConnector = mysql(publisher, 3306) myConnector.connect() profile = myConnector.getProfileData(name) image = myConnector.getImageData(profile["image"]) serverName = image["node"] # Lookup name in database to find network location of image nas = myConnector.getNASAddress(serverName)[0].split(":")[0] domain = str(uuid1()).replace("-", "") myConnector.insertInstance(domain, "-1", client.name, username, name) myConnector.disconnect() # transfer the archive over archive = image["archive"] copyFromNAS(archive, archive, nas, domain) # collect data about the archive contents disk = image["disk"] overlay = image["overlay"] config = image["config"] ram = str(profile["ram"]) vcpus = str(profile["vcpus"]) dest_dir = constants.get("default.imagedir") # clone the image and install into virsh virtHelper = subprocess.Popen( ["./cloneAndInstall.sh", archive, domain, disk, overlay, config, ram, vcpus, dest_dir], stdout=subprocess.PIPE, stderr=subprocess.PIPE, ) out, err = virtHelper.communicate() mac = out.decode().rstrip().replace(":", "-") result = {} result["mac"] = mac result["domain"] = domain return result
def instantiate(data): # Get posiotional arguments name = data['vm'] username = data['user'] # Get the IP of the publisher publisher = client.publisher[0] # Get image information myConnector = mysql(publisher, 3306) myConnector.connect() profile = myConnector.getProfileData(name) image = myConnector.getImageData(profile['image']) serverName = image['node'] # Lookup name in database to find network location of image nas = myConnector.getNASAddress(serverName)[0].split(':')[0] domain = str(uuid1()).replace('-', '') myConnector.insertInstance(domain, '-1', client.name, username, name) myConnector.disconnect() # transfer the archive over archive = image['archive'] copyFromNAS(archive, archive, nas, domain) # collect data about the archive contents disk = image['disk'] overlay = image['overlay'] config = image['config'] ram = str(profile['ram']) vcpus = str(profile['vcpus']) dest_dir = constants.get('default.imagedir') # clone the image and install into virsh virtHelper = subprocess.Popen(['./cloneAndInstall.sh', archive, domain, \ disk, overlay, config, ram, vcpus, \ dest_dir], stdout=subprocess.PIPE, \ stderr=subprocess.PIPE) out, err = virtHelper.communicate() mac = out.decode().rstrip().replace(':', '-') result = {} result['mac'] = mac result['domain'] = domain return result
def __init__(self, role = constants.get('default.role'), \ group = constants.get('default.group')): # invoke the constructor of the threading superclass super(ThunderRPC, self).__init__() # check the role of the service to determine the proper configuration if (role == 'PUBLISHER'): iface = constants.get('server.interface') port = SERVER_PORT elif (role == 'SUBSCRIBER'): iface = constants.get('default.interface') port = constants.get('default.port') else: print('Invalid role identifer. Must be either ' + \ '"PUBLISHER" or "SUBSCRIBER"') sys.exit(-1) # set the interface variable, which is the interface that we want to # bind the service to self._interface = iface # set the role ('PUBLISHER' | 'SUBSCRIBER') self._role = role # set the default nonce value. this is autogenerated, so the initial # value does not matter. self._nonce = 'DEADBEEF' iface_tool = interface() # get the IP address of the system self._IP = iface_tool.getAddr(iface) # create a TCP server, and bind it to the address of the desired # interface self._server = self.rpc.ThunderRPCServer((self._IP, port), \ self.rpc.RequestHandler) self._server._ThunderRPCInstance = self self._server.daemon = True # workaround for getting the port number for auto-assigned ports # (default behavior for clients) self._port = self._server.server_address[1] # create a dictionary mapping an event name to a function self._events = Dictionary() # create a dictionary mapping group name to an array of tuples (IP,Port) # these tuples represent the clients that are connecting to this service # if the role of this service is SUBSCRIBER then this dictionary should # always be empty. self._clients = Dictionary() print('Starting ThunderRPC Service (role = %s)' % role) print('-------------------------------------------------') print('Binding to IP address - %s:%s' % (self._IP, self._port)) # register some builtin events for metadata aggregation self.registerEvent('UTILIZATION', builtinEvents.utilization) self.registerEvent('SYSINFO', builtinEvents.sysInfo) # associate with a group self._group = group # give this node an arbitrary name self._name = getMAC(getnode()) # set the default publisher to None self._publisher = None if (role == 'PUBLISHER'): # startup a multicasting thread to respond to multicast messages self.mcastThread = threading.Thread(target=self.multicastThread) self.mcastThread.start() if (self.clients.contains(self.group)): c = self.clients.get(self.group) c.append((self.addr[0], int(self.addr[1]))) else: self.clients.append((self.group, [(self.addr[0], \ int(self.addr[1]))])) myConnector = mysql(self.addr[0], 3306) myConnector.connect() myConnector.insertNode(self.name, self.addr[0] + ':' + \ str(self.addr[1]), self.group) myConnector.disconnect() # recreate preseeding files from template generatePreseed(self._IP) # start the thread self.start() return
def __init__(self, role = constants.get('default.role'), \ group = constants.get('default.group')): # invoke the constructor of the threading superclass super(ThunderRPC, self).__init__() # check the role of the service to determine the proper configuration if (role == 'PUBLISHER'): iface = constants.get('server.interface') port = SERVER_PORT elif (role == 'SUBSCRIBER'): iface = constants.get('default.interface') port = constants.get('default.port') else: print('Invalid role identifer. Must be either ' + \ '"PUBLISHER" or "SUBSCRIBER"') sys.exit(-1) # set the interface variable, which is the interface that we want to # bind the service to self._interface = iface # set the role ('PUBLISHER' | 'SUBSCRIBER') self._role = role # set the default nonce value. this is autogenerated, so the initial # value does not matter. self._nonce = 'DEADBEEF' iface_tool = interface() # get the IP address of the system self._IP = iface_tool.getAddr(iface) # create a TCP server, and bind it to the address of the desired # interface self._server = self.rpc.ThunderRPCServer((self._IP, port), \ self.rpc.RequestHandler) self._server._ThunderRPCInstance = self self._server.daemon = True # workaround for getting the port number for auto-assigned ports # (default behavior for clients) self._port = self._server.server_address[1] # create a dictionary mapping an event name to a function self._events = Dictionary() # create a dictionary mapping group name to an array of tuples (IP,Port) # these tuples represent the clients that are connecting to this service # if the role of this service is SUBSCRIBER then this dictionary should # always be empty. self._clients = Dictionary() print('Starting ThunderRPC Service (role = %s)' % role) print('-------------------------------------------------') print('Binding to IP address - %s:%s' % (self._IP, self._port)) # register some builtin events for metadata aggregation self.registerEvent('UTILIZATION', builtinEvents.utilization) self.registerEvent('SYSINFO', builtinEvents.sysInfo) # associate with a group self._group = group # give this node an arbitrary name self._name = getMAC(getnode()) # set the default publisher to None self._publisher = None if (role == 'PUBLISHER'): # startup a multicasting thread to respond to multicast messages self.mcastThread = threading.Thread(target = self.multicastThread) self.mcastThread.start() if (self.clients.contains(self.group)): c = self.clients.get(self.group) c.append((self.addr[0], int(self.addr[1]))) else: self.clients.append((self.group, [(self.addr[0], \ int(self.addr[1]))])) myConnector = mysql(self.addr[0], 3306) myConnector.connect() myConnector.insertNode(self.name, self.addr[0] + ':' + \ str(self.addr[1]), self.group) myConnector.disconnect() # recreate preseeding files from template generatePreseed(self._IP) # start the thread self.start() return