예제 #1
0
 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]
예제 #2
0
    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()
예제 #3
0
    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()
예제 #4
0
 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]
예제 #5
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
예제 #6
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
예제 #7
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
예제 #8
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
예제 #9
0
    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
예제 #10
0
    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