Ejemplo n.º 1
0
 def pbs_service(self, rack_name=None):
     config = cm_config()
     username = config.get("cloudmesh.hpc.username")
     pbs = PBS(username, "india.futuregrid.org")
     dict_pbs_info = pbs.pbsnodes()
     dict_data = {}
     inventory = Inventory()
     racks = inventory.get_clusters()
     for rack in racks:
         rack_name = rack["cm_cluster"]
         dict_data[rack_name] = {}
         hosts = rack["cm_value"]
         for host in hosts:
             (hid, hlabel) = inventory.get_host_id_label(host, "public")
             utype = "unknown"
             if hlabel in dict_pbs_info:
                 server = dict_pbs_info[hlabel]
                 if "note" in server.keys():
                     note_value = server["note"]
                     # to compatible with the future change
                     if type(note_value) is dict:
                         utype = note_value["service"]
                     else:   # currently is a literal string for note
                         utype = note_value
             dict_data[rack_name][hid] = utype
     return dict_data
Ejemplo n.º 2
0
class RackData:
    # ONLY for debug test
    MY_DEBUG_FLAG = False

    # data valid time, unit second
    data_valid_time = 0

    inventory = None

    TEMPERATURE_NAME = "temperature"
    SERVICE_NAME = "service"
    LOCATION_TEMP = "temp"

    # three status of server refresh
    STATUS_NOT_READY = "not_ready"
    STATUS_REFRESH = "refresh"
    STATUS_READY = "ready"

    # default data valid time is set to 1800 seconds
    def __init__(self, valid_time=1800):
        self.data_valid_time = valid_time
        self.inventory = Inventory()

    def mydebug(self, msg):
        if self.MY_DEBUG_FLAG:
            log.debug(msg)

    # get/set data valid time in mongo db
    def get_data_valid_time(self):
        return self.data_valid_time

    def set_data_valid_time(self, valid_time):
        self.data_valid_time = valid_time if valid_time > 0 else 0

    # change refresh status
    def set_status_start_refresh(self, service_type, rack_name):
        self.mydebug(
            "set status start refresh for {0}-{1}".format(rack_name, service_type))
        query_dict = self.get_rack_query_dict(
            service_type, rack_name, self.LOCATION_TEMP)
        curr_time = datetime.now()
        element = {
            "rack_status": self.STATUS_REFRESH,
            "updated_node": 0,
            "cm_refresh": curr_time,
        }
        racks = {}
        for rack_name in query_dict:
            self.mydebug(
                "set_status_start_refresh rackname is: {0} ".format(rack_name))
            tmp_racks = self.inventory.get_clusters(rack_name)
            racks[rack_name] = tmp_racks[0]
            # self.mydebug("set_status_start_refresh racks[{0}] is: {1}".format(rack_name, racks[rack_name]))
            element['data'] = dict((h, None)
                                   for h in racks[rack_name]['cm_value'])
            self.partly_update(query_dict[rack_name], {"$set": element})

        self.mydebug(
            "Exit from status start refresh for {0}-{1}".format(rack_name, service_type))

    # get valid list of rack name
    # result: if rack_name is 'all', then ['india', 'echo', ...]
    # else if rack_name is a valid rack name, then ['rack_name.lower()']
    # else None
    def get_rack_name_list(self, rack_name="all"):
        self.mydebug("enter into get_rack_name_list of {0}".format(rack_name))
        racks = self.inventory.get_clusters()
        rack_name_list = [rack['cm_cluster'] for rack in racks]
        rack_name_lower = rack_name.lower()
        if rack_name_lower != 'all':
            rack_name_list = [
                rack_name_lower] if rack_name_lower in rack_name_list else None

        # self.mydebug("exit from get_rack_name_list {0}".format(rack_name_list))
        return rack_name_list

    # generate a query dict to query the rack table in inventory
    # location: 'temp' means cm_key is 'rack_temp_*' which is a temporary status table
    #           None means cm_key is 'rack_*', which is a permanent status table
    # result: if rack_name is 'all', then {"india": {query ...}, "echo": {query ...}, ... }
    #         else if rack_name is valid then {"rack_name": {query ...}}
    #         else None
    def get_rack_query_dict(self, service_type, rack_name, location=None):
        rack_name_list = self.get_rack_name_list(rack_name)
        if rack_name_list is None:
            return None

        query_dict = {}
        for rack_name in rack_name_list:
            query = {
                "cm_type": "inventory",
                "cm_kind": "rack",
                "cm_id": rack_name
            }
            if location:
                query["cm_key"] = "rack_{1}_{0}".format(service_type, location)
            else:
                query["cm_key"] = "rack_{0}".format(service_type)
            query_dict[rack_name] = query
        self.mydebug("get_rack_query_dict of {0}".format(query_dict))
        return query_dict

    def get_rack_info(self, query_dict):
        if query_dict is None:
            return None

        rack_info_dict = {}
        for rack_name in query_dict:
            rack_info_dict[rack_name] = self.inventory.find_one(
                query_dict[rack_name])
        # self.mydebug("get_rack_info of {0}".format(rack_info_dict.keys()))
        return rack_info_dict

    # result: {'rack_name': True, 'rack_name': False, ...}
    def can_start_refresh(self, service_type, rack_name):
        self.mydebug(
            "enter into can_start_refresh og {0}-{1}".format(rack_name, service_type))
        query_dict = self.get_rack_query_dict(
            service_type, rack_name, self.LOCATION_TEMP)
        rack_info_dict = self.get_rack_info(query_dict)
        if rack_info_dict is None:
            return None

        refresh_dict = {}
        for rack_name in rack_info_dict:
            flag_refresh = False
            rack_info = rack_info_dict[rack_name]
            status = rack_info['rack_status']
            if status == self.STATUS_NOT_READY:
                flag_refresh = True
            elif status == self.STATUS_READY or status == self.STATUS_REFRESH:
                flag_refresh = self.is_db_data_expired(rack_info['cm_refresh'])
            refresh_dict[rack_name] = flag_refresh

        self.mydebug("can_start_refresh of {0}".format(refresh_dict))
        return refresh_dict

    # projection query
    def partly_query(self, query, partly_view):
        if partly_view:
            return self.inventory.db_inventory.find_one(query, partly_view)
        return self.inventory.find_one(query)

    # update a part of document in database
    def partly_update(self, query, value, flag_upsert=False, flag_multi=False):
        if not value:
            return self.inventory.update(query)

        return self.inventory.db_inventory.update(query, value, upsert=flag_upsert, multi=flag_multi)

    # Usually called in a different process
    # update the temperature of a server
    # NOT support to update 'all'
    # The update of 'all' MUST be divided into serveral updates of each independent rack of 'all'
    # update the information of a server
    def server_refresh_update_temperature(self, rack_name, server, data):
        self.mydebug("enter into server_refresh_update_temperature update server {0} for {1}".format(
            server, rack_name))
        service_type = self.TEMPERATURE_NAME
        flag_refresh_success = False
        query_dict = self.get_rack_query_dict(
            service_type, rack_name, self.LOCATION_TEMP)
        rack_info_dict = self.get_rack_info(query_dict)
        rack_info = None
        if rack_info_dict:
            rack_info = rack_info_dict[rack_name]
            time_now = datetime.now()
            element = {}
            element['cm_refresh'] = time_now
            element['data.{0}'.format(server)] = data
            # atomic update
            update_result = self.inventory.db_inventory.find_and_modify(query=query_dict[rack_name], update={
                '$inc': {'updated_node': 1}, '$set': element}, new=True, fields={'updated_node': 1})

            if update_result['updated_node'] == rack_info['max_node']:
                self.partly_update(
                    query_dict[rack_name], {'$set': {'rack_status': self.STATUS_READY}})
                flag_refresh_success = True

            # update the normal record, which provides information to WEB page
            # After data of all servers in this rack are collected
            if flag_refresh_success:
                query_dict = self.get_rack_query_dict(service_type, rack_name)
                element = {}
                element['rack_status'] = self.STATUS_READY
                element['cm_refresh'] = time_now
                rack_info['data'][server] = data
                element['data'] = rack_info['data']
                self.mydebug(
                    "server_refresh_update_data, update rack {0} with data".format(rack_name))
                self.partly_update(query_dict[rack_name], {'$set': element})

        return flag_refresh_success

    # Usually called in a different process
    # update the service of a server
    def server_refresh_update_service(self, rack_name, data):
        self.mydebug(
            "enter into server_refresh_update_service update rack {0}".format(rack_name))
        service_type = self.SERVICE_NAME
        flag_refresh_success = False
        query_dict = {}
        for rack_name in data:
            tmp_result = self.get_rack_query_dict(
                service_type, rack_name, self.LOCATION_TEMP)
            query_dict[rack_name] = tmp_result[rack_name]
        rack_info_dict = self.get_rack_info(query_dict)
        if rack_info_dict is None:
            return flag_refresh_success

        for rack_name in rack_info_dict:
            rack_info = rack_info_dict[rack_name]
            time_now = datetime.now()
            element = {}
            element['cm_refresh'] = time_now
            element['updated_node'] = rack_info['max_node']
            element['rack_status'] = self.STATUS_READY
            element['data'] = data[rack_name]
            self.partly_update(query_dict[rack_name], {'$set': element})
            flag_refresh_success = True

            # update the normal record, which provides information to WEB page
            # After data of all servers in this rack are collected
            if flag_refresh_success:
                temp_query_dict = self.get_rack_query_dict(
                    service_type, rack_name)
                element = {}
                element['rack_status'] = self.STATUS_READY
                element['cm_refresh'] = time_now
                element['data'] = data[rack_name]
                self.mydebug(
                    "server_refresh_update_data, update rack {0} with data".format(rack_name))
                self.partly_update(
                    temp_query_dict[rack_name], {'$set': element})

        return flag_refresh_success

    # get data of a rack
    def get_rack_status_data(self, service_type, rack_name):
        rack_info_dict = self.get_rack_info(
            self.get_rack_query_dict(service_type, rack_name))
        if rack_info_dict is None:
            return None

        dict_result = {}
        for rack_name in rack_info_dict:
            dict_result[rack_name] = rack_info_dict[rack_name]["data"]

        self.mydebug(
            "exit from get_rack_status_data {0}-{1} with data".format(rack_name, service_type))
        return dict_result

    # get temperature data of a rack
    def get_rack_temperature_data(self, rack_name):
        return self.get_rack_status_data(self.TEMPERATURE_NAME, rack_name)

    # get service data of a rack
    def get_rack_service_data(self, rack_name):
        return self.get_rack_status_data(self.SERVICE_NAME, rack_name)

    # whether the data of a rack is ready or not
    def is_rack_data_ready(self, service_type, rack_name, refresh_flag=False):
        location = self.LOCATION_TEMP if refresh_flag else None
        query_dict = self.get_rack_query_dict(
            service_type, rack_name, location)
        rack_info_dict = self.get_rack_info(query_dict)
        if rack_info_dict is None:
            return False

        flag_ready = False
        for rack_name in rack_info_dict:
            #self.mydebug("{0} data is {1}".format(rack_name, rack_info_dict[rack_name]))
            rack_info = rack_info_dict[rack_name]

            if rack_info['rack_status'] == self.STATUS_READY:
                flag_ready = not self.is_db_data_expired(
                    rack_info["cm_refresh"])
            if not flag_ready:
                break
        return flag_ready

    # check data is ready or not in temp refresh db
    def is_refresh_rack_data_ready(self, service_type, rack_name):
        return self.is_rack_data_ready(service_type, rack_name, True)

    # whether the temperature data of a rack is ready or not
    def is_rack_temperature_ready(self, rack_name):
        return self.is_rack_data_ready(self.TEMPERATURE_NAME)

    # whether the service data of a rack is ready or not
    def is_rack_service_ready(self, rack_name):
        return self.is_rack_data_ready(self.SERVICE_NAME, rack_name)

    # check data in mongo db expired or not
    def is_db_data_expired(self, db_time):
        flag_expired = False
        time_interval = timedelta(seconds=self.data_valid_time)
        if (datetime.now() > db_time + time_interval):
            flag_expired = True
        return flag_expired
Ejemplo n.º 3
0
class RackData:
    # ONLY for debug test
    MY_DEBUG_FLAG = False

    # data valid time, unit second
    data_valid_time = 0

    inventory = None

    TEMPERATURE_NAME = "temperature"
    SERVICE_NAME = "service"
    LOCATION_TEMP = "temp"

    # three status of server refresh
    STATUS_NOT_READY = "not_ready"
    STATUS_REFRESH = "refresh"
    STATUS_READY = "ready"

    # default data valid time is set to 1800 seconds
    def __init__(self, valid_time=1800):
        self.data_valid_time = valid_time
        self.inventory = Inventory()

    def mydebug(self, msg):
        if self.MY_DEBUG_FLAG:
            log.debug(msg)

    # get/set data valid time in mongo db
    def get_data_valid_time(self):
        return self.data_valid_time

    def set_data_valid_time(self, valid_time):
        self.data_valid_time = valid_time if valid_time > 0 else 0

    # change refresh status
    def set_status_start_refresh(self, service_type, rack_name):
        self.mydebug("set status start refresh for {0}-{1}".format(
            rack_name, service_type))
        query_dict = self.get_rack_query_dict(service_type, rack_name,
                                              self.LOCATION_TEMP)
        curr_time = datetime.now()
        element = {
            "rack_status": self.STATUS_REFRESH,
            "updated_node": 0,
            "cm_refresh": curr_time,
        }
        racks = {}
        for rack_name in query_dict:
            self.mydebug(
                "set_status_start_refresh rackname is: {0} ".format(rack_name))
            tmp_racks = self.inventory.get_clusters(rack_name)
            racks[rack_name] = tmp_racks[0]
            #self.mydebug("set_status_start_refresh racks[{0}] is: {1}".format(rack_name, racks[rack_name]))
            element['data'] = dict(
                (h, None) for h in racks[rack_name]['cm_value'])
            self.partly_update(query_dict[rack_name], {"$set": element})

        self.mydebug("Exit from status start refresh for {0}-{1}".format(
            rack_name, service_type))

    # get valid list of rack name
    # result: if rack_name is 'all', then ['india', 'echo', ...]
    #         else if rack_name is a valid rack name, then ['rack_name.lower()']
    #         else None
    def get_rack_name_list(self, rack_name="all"):
        self.mydebug("enter into get_rack_name_list of {0}".format(rack_name))
        racks = self.inventory.get_clusters()
        rack_name_list = [rack['cm_cluster'] for rack in racks]
        rack_name_lower = rack_name.lower()
        if rack_name_lower != 'all':
            rack_name_list = [rack_name_lower
                              ] if rack_name_lower in rack_name_list else None

        #self.mydebug("exit from get_rack_name_list {0}".format(rack_name_list))
        return rack_name_list

    # generate a query dict to query the rack table in inventory
    # location: 'temp' means cm_key is 'rack_temp_*' which is a temporary status table
    #           None means cm_key is 'rack_*', which is a permanent status table
    # result: if rack_name is 'all', then {"india": {query ...}, "echo": {query ...}, ... }
    #         else if rack_name is valid then {"rack_name": {query ...}}
    #         else None
    def get_rack_query_dict(self, service_type, rack_name, location=None):
        rack_name_list = self.get_rack_name_list(rack_name)
        if rack_name_list is None:
            return None

        query_dict = {}
        for rack_name in rack_name_list:
            query = {
                "cm_type": "inventory",
                "cm_kind": "rack",
                "cm_id": rack_name
            }
            if location:
                query["cm_key"] = "rack_{1}_{0}".format(service_type, location)
            else:
                query["cm_key"] = "rack_{0}".format(service_type)
            query_dict[rack_name] = query
        self.mydebug("get_rack_query_dict of {0}".format(query_dict))
        return query_dict

    def get_rack_info(self, query_dict):
        if query_dict is None:
            return None

        rack_info_dict = {}
        for rack_name in query_dict:
            rack_info_dict[rack_name] = self.inventory.find_one(
                query_dict[rack_name])
        #self.mydebug("get_rack_info of {0}".format(rack_info_dict.keys()))
        return rack_info_dict

    # result: {'rack_name': True, 'rack_name': False, ...}
    def can_start_refresh(self, service_type, rack_name):
        self.mydebug("enter into can_start_refresh og {0}-{1}".format(
            rack_name, service_type))
        query_dict = self.get_rack_query_dict(service_type, rack_name,
                                              self.LOCATION_TEMP)
        rack_info_dict = self.get_rack_info(query_dict)
        if rack_info_dict is None:
            return None

        refresh_dict = {}
        for rack_name in rack_info_dict:
            flag_refresh = False
            rack_info = rack_info_dict[rack_name]
            status = rack_info['rack_status']
            if status == self.STATUS_NOT_READY:
                flag_refresh = True
            elif status == self.STATUS_READY or status == self.STATUS_REFRESH:
                flag_refresh = self.is_db_data_expired(rack_info['cm_refresh'])
            refresh_dict[rack_name] = flag_refresh

        self.mydebug("can_start_refresh of {0}".format(refresh_dict))
        return refresh_dict

    # projection query
    def partly_query(self, query, partly_view):
        if partly_view:
            return self.inventory.db_inventory.find_one(query, partly_view)
        return self.inventory.find_one(query)

    # update a part of document in database
    def partly_update(self, query, value, flag_upsert=False, flag_multi=False):
        if not value:
            return self.inventory.update(query)

        return self.inventory.db_inventory.update(query,
                                                  value,
                                                  upsert=flag_upsert,
                                                  multi=flag_multi)

    # Usually called in a different process
    # update the temperature of a server
    # NOT support to update 'all'
    # The update of 'all' MUST be divided into serveral updates of each independent rack of 'all'
    # update the information of a server
    def server_refresh_update_temperature(self, rack_name, server, data):
        self.mydebug(
            "enter into server_refresh_update_temperature update server {0} for {1}"
            .format(server, rack_name))
        service_type = self.TEMPERATURE_NAME
        flag_refresh_success = False
        query_dict = self.get_rack_query_dict(service_type, rack_name,
                                              self.LOCATION_TEMP)
        rack_info_dict = self.get_rack_info(query_dict)
        rack_info = None
        if rack_info_dict:
            rack_info = rack_info_dict[rack_name]
            time_now = datetime.now()
            element = {}
            element['cm_refresh'] = time_now
            element['data.{0}'.format(server)] = data
            # atomic update
            update_result = self.inventory.db_inventory.find_and_modify(
                query=query_dict[rack_name],
                update={
                    '$inc': {
                        'updated_node': 1
                    },
                    '$set': element
                },
                new=True,
                fields={'updated_node': 1})

            if update_result['updated_node'] == rack_info['max_node']:
                self.partly_update(
                    query_dict[rack_name],
                    {'$set': {
                        'rack_status': self.STATUS_READY
                    }})
                flag_refresh_success = True

            # update the normal record, which provides information to WEB page
            # After data of all servers in this rack are collected
            if flag_refresh_success:
                query_dict = self.get_rack_query_dict(service_type, rack_name)
                element = {}
                element['rack_status'] = self.STATUS_READY
                element['cm_refresh'] = time_now
                rack_info['data'][server] = data
                element['data'] = rack_info['data']
                self.mydebug(
                    "server_refresh_update_data, update rack {0} with data".
                    format(rack_name))
                self.partly_update(query_dict[rack_name], {'$set': element})

        return flag_refresh_success

    # Usually called in a different process
    # update the service of a server
    def server_refresh_update_service(self, rack_name, data):
        self.mydebug(
            "enter into server_refresh_update_service update rack {0}".format(
                rack_name))
        service_type = self.SERVICE_NAME
        flag_refresh_success = False
        query_dict = {}
        for rack_name in data:
            tmp_result = self.get_rack_query_dict(service_type, rack_name,
                                                  self.LOCATION_TEMP)
            query_dict[rack_name] = tmp_result[rack_name]
        rack_info_dict = self.get_rack_info(query_dict)
        if rack_info_dict is None:
            return flag_refresh_success

        for rack_name in rack_info_dict:
            rack_info = rack_info_dict[rack_name]
            time_now = datetime.now()
            element = {}
            element['cm_refresh'] = time_now
            element['updated_node'] = rack_info['max_node']
            element['rack_status'] = self.STATUS_READY
            element['data'] = data[rack_name]
            self.partly_update(query_dict[rack_name], {'$set': element})
            flag_refresh_success = True

            # update the normal record, which provides information to WEB page
            # After data of all servers in this rack are collected
            if flag_refresh_success:
                temp_query_dict = self.get_rack_query_dict(
                    service_type, rack_name)
                element = {}
                element['rack_status'] = self.STATUS_READY
                element['cm_refresh'] = time_now
                element['data'] = data[rack_name]
                self.mydebug(
                    "server_refresh_update_data, update rack {0} with data".
                    format(rack_name))
                self.partly_update(temp_query_dict[rack_name],
                                   {'$set': element})

        return flag_refresh_success

    # get data of a rack
    def get_rack_status_data(self, service_type, rack_name):
        rack_info_dict = self.get_rack_info(
            self.get_rack_query_dict(service_type, rack_name))
        if rack_info_dict is None:
            return None

        dict_result = {}
        for rack_name in rack_info_dict:
            dict_result[rack_name] = rack_info_dict[rack_name]["data"]

        self.mydebug("exit from get_rack_status_data {0}-{1} with data".format(
            rack_name, service_type))
        return dict_result

    # get temperature data of a rack
    def get_rack_temperature_data(self, rack_name):
        return self.get_rack_status_data(self.TEMPERATURE_NAME, rack_name)

    # get service data of a rack
    def get_rack_service_data(self, rack_name):
        return self.get_rack_status_data(self.SERVICE_NAME, rack_name)

    # whether the data of a rack is ready or not
    def is_rack_data_ready(self, service_type, rack_name, refresh_flag=False):
        location = self.LOCATION_TEMP if refresh_flag else None
        query_dict = self.get_rack_query_dict(service_type, rack_name,
                                              location)
        rack_info_dict = self.get_rack_info(query_dict)
        if rack_info_dict is None:
            return False

        flag_ready = False
        for rack_name in rack_info_dict:
            #self.mydebug("{0} data is {1}".format(rack_name, rack_info_dict[rack_name]))
            rack_info = rack_info_dict[rack_name]

            if rack_info['rack_status'] == self.STATUS_READY:
                flag_ready = not self.is_db_data_expired(
                    rack_info["cm_refresh"])
            if not flag_ready:
                break
        return flag_ready

    # check data is ready or not in temp refresh db
    def is_refresh_rack_data_ready(self, service_type, rack_name):
        return self.is_rack_data_ready(service_type, rack_name, True)

    # whether the temperature data of a rack is ready or not
    def is_rack_temperature_ready(self, rack_name):
        return self.is_rack_data_ready(self.TEMPERATURE_NAME)

    # whether the service data of a rack is ready or not
    def is_rack_service_ready(self, rack_name):
        return self.is_rack_data_ready(self.SERVICE_NAME, rack_name)

    # check data in mongo db expired or not
    def is_db_data_expired(self, db_time):
        flag_expired = False
        time_interval = timedelta(seconds=self.data_valid_time)
        if (datetime.now() > db_time + time_interval):
            flag_expired = True
        return flag_expired