HEX
Server: Apache/2.4.52 (Ubuntu)
System: Linux WebLive 5.15.0-79-generic #86-Ubuntu SMP Mon Jul 10 16:07:21 UTC 2023 x86_64
User: ubuntu (1000)
PHP: 7.4.33
Disabled: pcntl_alarm,pcntl_fork,pcntl_waitpid,pcntl_wait,pcntl_wifexited,pcntl_wifstopped,pcntl_wifsignaled,pcntl_wifcontinued,pcntl_wexitstatus,pcntl_wtermsig,pcntl_wstopsig,pcntl_signal,pcntl_signal_get_handler,pcntl_signal_dispatch,pcntl_get_last_error,pcntl_strerror,pcntl_sigprocmask,pcntl_sigwaitinfo,pcntl_sigtimedwait,pcntl_exec,pcntl_getpriority,pcntl_setpriority,pcntl_async_signals,pcntl_unshare,
Upload Files
File: //usr/local/qcloud/monitor/barad/plugin/collector/utils/collect_vm_msg.py
import threading
import os
import constant
import re
import time
import urllib2
from cutils import get_url, console_logger, generate_config, is_metal, CommUtils, is_minios, local_ip
import json

def singleton(cls):
    instances = {}
    lock = threading.Lock()

    def wrapper(*args, **kwargs):
        if cls not in instances:
            with lock:
                if cls not in instances:
                    instances[cls] = cls(*args, **kwargs)
        return instances[cls]
    return wrapper

@singleton
class CollectVmMesg(object):
    def __init__(self, executor = None):
        self.ins_id_mutex = threading.Lock()
        self.app_id_mutex  = threading.Lock()
        self.disk_id_mutex  = threading.Lock()
        self.host_sn_mutex  = threading.Lock()
        self.uuid_mutex = threading.Lock()
        self.region_mutex = threading.Lock()
        self.ntptime_offset_mutex = threading.Lock()
        self.retry_intervals = [60, 600, 1800, 3600]
        self.metadata = ''
        self.ntptime_offset = 0
        self.barad_version  = ""
        self.logger = executor.logger() if executor is not None else console_logger()
        self.logger.info("CollectVmMesg init ...")

        self._client_key = ''
        self.project_id_last_update_time = 0
        self.request_data_mesg = {
                                "app_id":{"request_fail_count":-1, "request_data": None, "request_last_fail_time": 0, "mutex":self.app_id_mutex},
                                "ins_id":{"request_fail_count":-1, "request_data": None, "request_last_fail_time": 0, "mutex":self.ins_id_mutex},
                                "disk_id":{"request_fail_count":-1, "request_data": None, "request_last_fail_time": 0, "mutex":self.disk_id_mutex},
                                "host_sn":{"request_fail_count":-1, "request_data": None, "request_last_fail_time": 0, "mutex":self.host_sn_mutex},
                                "uuid":{"request_fail_count":-1, "request_data": None, "request_last_fail_time": 0, "mutex":self.uuid_mutex},
                                "region":{"request_fail_count":-1, "request_data": None, "request_last_fail_time": 0, "mutex":self.region_mutex}
                            }

    def request_metadata(self, request_name, url):
        request_data = self.request_data_mesg[request_name]
        if request_data.get("request_data"):
            return request_data.get("request_data")

        if request_data.get("request_last_fail_time") != 0 and (int(time.time()) - request_data.get("request_last_fail_time") < self.retry_intervals[request_data.get("request_fail_count")]):
            return request_data.get("request_data")

        if request_data["mutex"].acquire():
            if request_data.get("request_data"):
                request_data["mutex"].release()
                return request_data.get("request_data") 
            try:
                self.logger.info("request metadata:%s" %url)
                response = urllib2.urlopen(url, timeout=2)
                content = response.read()
                if len(content) > 0 and len(content.splitlines()) == 1:
                    request_data["request_data"] = content
                    request_data["request_last_fail_time"] = 0
                    request_data["mutex"].release()
                    return request_data.get("request_data")
            except Exception as e:
                request_data["request_data"] = ''
                request_data["request_last_fail_time"] = int(time.time())
                if request_data.get("request_fail_count") < len(self.retry_intervals) - 1:
                    request_data["request_fail_count"] += 1
                self.logger.error("get %s from metadata fail,  %s ,after %s s request!" % (url ,e, self.retry_intervals[request_data["request_fail_count"]]))
            request_data["mutex"].release()
            return request_data.get("request_data")       
        
    def get_vm_project_id(self):
        return 0

    def get_vm_instance_id(self):
        request_name = "ins_id"
        if self.metadata == '':
            self.metadata = generate_config(constant.PLUGIN_CONFIG_PATH, "MetaDataServer")
        url = self.metadata['metadata_url'] + 'instance-id'
        return self.request_metadata(request_name, url)            
    
    def get_vm_app_id(self):
        request_name = "app_id"
        if self.metadata == '':
            self.metadata = generate_config(constant.PLUGIN_CONFIG_PATH, "MetaDataServer")
        url = self.metadata['metadata_url'] + 'app-id'
        return self.request_metadata(request_name, url)

    def get_diskid(self, serial):
        request_name = "disk_id"
        if self.metadata == '':
            self.metadata = generate_config(constant.PLUGIN_CONFIG_PATH, "MetaDataServer") 
        url = ""
        if re.match("vd",serial) is None:
            url=self.metadata['metadata_url'] + 'bare-metal/block_disk_mapping/%s' % serial
        else:
            url=self.metadata['metadata_url'] + 'physical_disks_mapping/%s' % serial
        return self.request_metadata(request_name, url)             

    def get_sn(self):
        request_name = "host_sn"
        if self.metadata == '':
            self.metadata = generate_config(constant.PLUGIN_CONFIG_PATH, "MetaDataServer")
        url = self.metadata['metadata_url'] + 'host-sn'
        return self.request_metadata(request_name, url)
    
    def get_vm_region(self):
        request_name = "region"
        if self.metadata == '':
            self.metadata = generate_config(constant.PLUGIN_CONFIG_PATH, "MetaDataServer")
        url =  self.metadata['new_metadata_url'] + 'placement/region'
        content = self.request_metadata(request_name, url)
        if len(content) > 0 and len(content.splitlines()) == 1:
            try:
                with open(constant.PLUGIN_REGION_PATH, 'r') as f:
                    longRegionToAbbrRegion = json.load(f)
                    region = longRegionToAbbrRegion.get(content, '')
                    return region
            except Exception as e:
                self.logger.error("get_vm_region from metadata fail,  %s" % e)
        return None


    def get_ntp_server(self):
        self.ntpserver = generate_config(constant.PLUGIN_CONFIG_PATH,"NtpServer")
        if self.ntpserver.has_key("ntp_url"):
            return self.ntpserver['ntp_url']
        else:
            return None

    def get_vm_uuid_by_file(self):
        if is_minios():
            return ''
        if self.request_data_mesg["uuid"]["mutex"].acquire():
            if not is_metal():
                #get cvm uuid from dmi info
                uuid_serial = "/sys/class/dmi/id/product_serial"
                if os.path.exists(uuid_serial):
                    with open(uuid_serial,'r') as fd:
                        first_char = fd.read(1)
                        fd.seek(0)
                        if not first_char.isalnum():
                            mount_file = "/etc/uuid"
                            if os.path.exists(mount_file):
                                with open('/etc/uuid', 'r') as f:
                                    uuid = f.read().strip()
                                uuid_value = uuid.split('=')[-1].strip()
                                with open('/etc/uuid_to_serial', 'w') as f:
                                    f.write(uuid_value)
                                mount_command = "mount --bind /etc/uuid_to_serial /sys/class/dmi/id/product_serial"
                                subprocess.Popen(mount_command, shell=True) 
                        vm_uuid = fd.readline().strip().lower()
                        self.request_data_mesg["uuid"]["mutex"].release()
                        return vm_uuid
                uuid_path='/etc/uuid'
                if os.path.exists(uuid_path):
                    with open(uuid_path,'r') as f:
                        vm_uuid = f.read().split('=')[1].replace('"','').replace('\'','').strip()
                        self.request_data_mesg["uuid"]["mutex"].release()
                        return vm_uuid
            self.request_data_mesg["uuid"]["mutex"].release()

    def get_vm_uuid(self):
        request_name = "uuid"
        vm_uuid = ''
        if self.request_data_mesg["uuid"]["request_data"]:
            return self.request_data_mesg["uuid"]["request_data"]
        vm_uuid = self.get_vm_uuid_by_file()
        if vm_uuid:
            self.request_data_mesg["uuid"]["request_data"] = vm_uuid
        if self.metadata == '':
            self.metadata = generate_config(constant.PLUGIN_CONFIG_PATH, "MetaDataServer")
        url = self.metadata['metadata_url'] + 'uuid'
        content = self.request_metadata(request_name, url) 
        pattern = "^[0-9a-z]{8}-[0-9a-z]{4}-[0-9a-z]{4}-[0-9a-z]{4}-[0-9a-z]{12}$"
        if re.match(pattern, content):
            vm_uuid = content
        else:
            vm_uuid = ''
        return vm_uuid
    
    def get_barad_version(self):
        if self.barad_version != "":
            return self.barad_version
        try:
            config_name = generate_config(constant.COMMON_CONFIG_PATH,"name")
            self.barad_version = config_name['agent_version'].strip().lstrip("v")
        except Exception, e:
            self.barad_version = ""
        return self.barad_version    
        
    @staticmethod
    def get_lanip():
        return CollectVmMesg.get_vmip()

    @staticmethod
    def get_vmip():
        return local_ip()
    
    @staticmethod
    def get_cbs_diskid(serial):
        disk_id = ''
        try:
            cmd = "ls -l  /dev/disk/by-id |sort -r -t '/' -k 3 |grep -o -E 'disk-[0-9A-Za-z]{8}'|uniq"
            output = CommUtils.ExecuteTimeoutCommand(cmd, 3).split("\n")
            disk_id = list(output)
            return disk_id
        except Exception, e:
            disk_id = ''
        return disk_id
    
    def set_ntptime_offset(self, offset):
        if self.ntptime_offset_mutex.acquire():
            self.ntptime_offset = offset
            self.ntptime_offset_mutex.release()
            
    def get_ntptime_offset(self):
        return self.ntptime_offset

    def get_client_key(self):
        CLIENT_KEY_PATH = '/usr/local/qcloud/monitor/config/clientKey.ini'
        if len(self._client_key) > 0:
            return self._client_key
        try:
            if os.path.isfile(CLIENT_KEY_PATH):
                key_file = open(CLIENT_KEY_PATH, "r")
                lines = key_file.readlines()
                for line in lines:
                    if line.startswith("clientKey") and line.find('=')>0 :
                        self._client_key = line.split('=')[1].strip()
                        break
                key_file.close()
            else:
                import urllib2,json,time
                import constant
                url = get_url('UpdateServer','new_update_url','update_url')
                config = generate_config(constant.PLUGIN_CONFIG_PATH, 'UpdateServer')
                uuid = self.get_vm_uuid()
                req = {
                    "version": "v1.0",
                    "caller": "agent",
                    "password": "",
                    "callee": "autoupdate",
                    "eventId": 101,
                    "timestamp": time.time(),
                    'interface': {
                        "interfaceName": "GetClientKey",
                        "para": {
                            "uuid": uuid
                        }
                    }
                }
                http_ret = urllib2.urlopen(url, json.dumps(req), float(config['update_timeout']))
                response = http_ret.read()
                json_resp = json.loads(response)
                retcode = int(json_resp["returnCode"])
                if retcode != 0:
                    print json_resp["returnMsg"]
                else: 
                    self._client_key = json_resp["returnData"]["clientKey"]
                    dir, file = os.path.split(CLIENT_KEY_PATH)
                    if not os.path.exists(dir):
                        os.makedirs(dir)
                    with open(CLIENT_KEY_PATH, "w") as f:
                        str = 'clientKey=' + self._client_key
                        f.writelines(str)

        except Exception,e:
            self.logger.error("get client key fail:%s" %e)
        return self._client_key