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