#/usr/bin/python from OvmCommonModule import * from OVSSiteRMServer import get_master_ip, register_server from OVSCommons import * from OVSXMonitor import xen_get_xm_info from OVSXSysInfo import get_agent_version from OVSSiteRMServer import get_srv_agent_status from OVSXMonitor import sys_perf_info from OVSDB import db_get_vm from OvmStoragePoolModule import OvmStoragePool from OvmHaHeartBeatModule import OvmHaHeartBeat import re logger = OvmLogger('OvmHost') class OvmHostEncoder(json.JSONEncoder): def default(self, obj): if not isinstance(obj, OvmHost): raise Exception("%s is not instance of OvmHost"%type(obj)) dct = {} safeDictSet(obj, dct, 'masterIp') safeDictSet(obj, dct, 'cpuNum') safeDictSet(obj, dct, 'cpuSpeed') safeDictSet(obj, dct, 'totalMemory') safeDictSet(obj, dct, 'freeMemory') safeDictSet(obj, dct, 'dom0Memory') safeDictSet(obj, dct, 'agentVersion') safeDictSet(obj, dct, 'name') safeDictSet(obj, dct, 'dom0KernelVersion') safeDictSet(obj, dct, 'hypervisorVersion') return dct def fromOvmHost(host): return normalizeToGson(json.dumps(host, cls=OvmHostEncoder)) class OvmHost(OvmObject): masterIp = '' cpuNum = 0 cpuSpeed = 0 totalMemory = 0 freeMemory = 0 dom0Memory = 0 agentVersion = '' name = '' dom0KernelVersion = '' hypervisorVersion = '' def _getVmPathFromPrimaryStorage(self, vmName): ''' we don't have a database to store vm states, so there is no way to retrieve information of a vm when it was already stopped. The trick is to try to find the vm path in primary storage then we can read information from its configure file. ''' mps = OvmStoragePool()._getAllMountPoints() vmPath = None for p in mps: vmPath = join(p, 'running_pool', vmName) if exists(vmPath): break if not vmPath: logger.error(self._getVmPathFromPrimaryStorage, "Cannot find link for %s in any primary storage, the vm was really gone!"%vmName) raise Exception("Cannot find link for %s in any primary storage, the vm was really gone!"%vmName) return vmPath def _vmNameToPath(self, vmName): # the xen_get_vm_path always sucks!!! #return successToMap((vmName))['path'] return self._getVmPathFromPrimaryStorage(vmName) def _getAllDomains(self): stdout = timeout_command(["xm", "list"]) l = [ line.split()[:2] for line in stdout.splitlines() ] l = [ (name, id) for (name, id) in l if name not in ("Name", "Domain-0") ] return l def _getDomainIdByName(self, vmName): l = self._getAllDomains() for name, id in l: if vmName == name: return id raise NoVmFoundException("No domain id for %s found"%vmName) @staticmethod def registerAsMaster(hostname, username="oracle", password="password", port=8899, isSsl=False): try: logger.debug(OvmHost.registerAsMaster, "ip=%s, username=%s, password=%s, port=%s, isSsl=%s"%(hostname, username, password, port, isSsl)) exceptionIfNoSuccess(register_server(hostname, 'site', False, username, password, port, isSsl), "Register %s as site failed"%hostname) exceptionIfNoSuccess(register_server(hostname, 'utility', False, username, password, port, isSsl), "Register %s as utility failed"%hostname) rs = SUCC() return rs except Exception, e: errmsg = fmt_err_msg(e) logger.error(OvmHost.registerAsMaster, errmsg) raise XmlRpcFault(toErrCode(OvmHost, OvmHost.registerAsMaster), errmsg) @staticmethod def registerAsVmServer(hostname, username="oracle", password="password", port=8899, isSsl=False): try: logger.debug(OvmHost.registerAsVmServer, "ip=%s, username=%s, password=%s, port=%s, isSsl=%s"%(hostname, username, password, port, isSsl)) exceptionIfNoSuccess(register_server(hostname, 'xen', False, username, password, port, isSsl), "Register %s as site failed"%hostname) rs = SUCC() return rs except Exception, e: errmsg = fmt_err_msg(e) logger.error(OvmHost.registerAsVmServer, errmsg) raise XmlRpcFault(toErrCode(OvmHost, OvmHost.registerAsVmServer), errmsg) @staticmethod def ping(hostname): try: logger.debug(OvmHost.ping, "ping %s"%hostname) exceptionIfNoSuccess(get_srv_agent_status(hostname), "Ovs agent is down") rs = SUCC() return rs except Exception, e: errmsg = fmt_err_msg(e) logger.error(OvmHost.ping, errmsg) raise XmlRpcFault(toErrCode(OvmHost, OvmHost.ping, errmsg)) @staticmethod def getDetails(): try: obj = OvmHost() masterIp = successToMap(get_master_ip()) safeSetAttr(obj, 'masterIp', masterIp['ip']) xmInfo = successToMap(xen_get_xm_info()) totalMemory = MtoBytes(long(xmInfo['total_memory'])) safeSetAttr(obj, 'totalMemory', totalMemory) freeMemory = MtoBytes(long(xmInfo['free_memory'])) safeSetAttr(obj, 'freeMemory', freeMemory) dom0Memory = totalMemory - freeMemory safeSetAttr(obj, 'dom0Memory', dom0Memory) cpuNum = int(xmInfo['nr_cpus']) safeSetAttr(obj, 'cpuNum', cpuNum) cpuSpeed = int(xmInfo['cpu_mhz']) safeSetAttr(obj, 'cpuSpeed', cpuSpeed) name = xmInfo['host'] safeSetAttr(obj, 'name', name) dom0KernelVersion = xmInfo['release'] safeSetAttr(obj, 'dom0KernelVersion', dom0KernelVersion) hypervisorVersion = xmInfo['xen_major'] + '.' + xmInfo['xen_minor'] + xmInfo['xen_extra'] safeSetAttr(obj, 'hypervisorVersion', hypervisorVersion) agtVersion = successToMap(get_agent_version()) safeSetAttr(obj, 'agentVersion', agtVersion['agent_version']) res = fromOvmHost(obj) logger.debug(OvmHost.getDetails, res) return res except Exception, e: errmsg = fmt_err_msg(e) logger.error(OvmHost.getDetails, errmsg) raise XmlRpcFault(toErrCode(OvmHost, OvmHost.getDetails), errmsg) @staticmethod def getPerformanceStats(bridgeName): try: rxBytesPath = join("/sys/class/net/", bridgeName, "statistics/rx_bytes") txBytesPath = join("/sys/class/net/", bridgeName, "statistics/tx_bytes") if not exists(rxBytesPath): raise Exception("Cannot find %s"%rxBytesPath) if not exists(txBytesPath): raise Exception("Cannot find %s"%txBytesPath) rxBytes = long(doCmd(['cat', rxBytesPath])) / 1000 txBytes = long(doCmd(['cat', txBytesPath])) / 1000 sysPerf = successToMap(sys_perf_info()) cpuUtil = float(100 - float(sysPerf['cpu_idle']) * 100) freeMemory = MtoBytes(long(sysPerf['mem_free'])) xmInfo = successToMap(xen_get_xm_info()) totalMemory = MtoBytes(long(xmInfo['total_memory'])) rs = toGson({"cpuUtil":cpuUtil, "totalMemory":totalMemory, "freeMemory":freeMemory, "rxBytes":rxBytes, "txBytes":txBytes}) logger.info(OvmHost.getPerformanceStats, rs) return rs except Exception, e: errmsg = fmt_err_msg(e) logger.error(OvmHost.getPerformanceStats, errmsg) raise XmlRpcFault(toErrCode(OvmHost, OvmHost.getPerformanceStats), errmsg) @staticmethod def getAllVms(): try: l = OvmHost()._getAllDomains() dct = {} host = OvmHost() for name, id in l: vmPath = host._getVmPathFromPrimaryStorage(name) vmStatus = db_get_vm(vmPath) dct[name] = vmStatus['status'] rs = toGson(dct) logger.info(OvmHost.getAllVms, rs) return rs except Exception, e: errmsg = fmt_err_msg(e) logger.error(OvmHost.getAllVms, errmsg) raise XmlRpcFault(toErrCode(OvmHost, OvmHost.getAllVms), errmsg) @staticmethod def fence(ip): # try 3 times to avoid race condition that read when heartbeat file is being written def getTimeStamp(hbFile): for i in range(1, 3): f = open(hbFile, 'r') str = f.readline() items = re.findall(HEARTBEAT_TIMESTAMP_PATTERN, str) if len(items) == 0: logger.debug(OvmHost.fence, "Get an incorrect heartbeat data %s, will retry %s times" % (str, 3-i)) f.close() time.sleep(5) else: f.close() timestamp = items[0] return timestamp.lstrip('').rstrip('') # totally check in 6 mins, the update frequency is 2 mins def check(hbFile): for i in range(1, 6): ts = getTimeStamp(hbFile) time.sleep(60) nts = getTimeStamp(hbFile) if ts != nts: return True else: logger.debug(OvmHost.fence, '%s is not updated, old value=%s, will retry %s times'%(hbFile, ts, 6-i)) return False try: mountpoints = OvmStoragePool()._getAllMountPoints() hbFile = None for m in mountpoints: p = join(m, HEARTBEAT_DIR, ipToHeartBeatFileName(ip)) if exists(p): hbFile = p break if not hbFile: raise Exception('Can not find heartbeat file for %s in pools %s'%(ip, mountpoints)) rs = toGson({"isLive":check(hbFile)}) logger.debug(OvmHost.fence, rs) return rs except Exception, e: errmsg = fmt_err_msg(e) logger.error(OvmHost.fence, errmsg) raise XmlRpcFault(toErrCode(OvmHost, OvmHost.fence), errmsg) @staticmethod def setupHeartBeat(poolUuid, ip): try: sr = OvmStoragePool()._getSrByNameLable(poolUuid) OvmHaHeartBeat.start(sr.mountpoint, ip) return SUCC() except Exception, e: errmsg = fmt_err_msg(e) logger.error(OvmHost.setupHeartBeat, errmsg) raise XmlRpcFault(toErrCode(OvmHost, OvmHost.setupHeartBeat), errmsg) @staticmethod def pingAnotherHost(ip): try: doCmd(['ping', '-c', '1', '-n', '-q', ip]) return SUCC() except Exception, e: errmsg = fmt_err_msg(e) logger.error(OvmHost.pingAnotherHost, errmsg) raise XmlRpcFault(toErrCode(OvmHost, OvmHost.pingAnotherHost), errmsg) if __name__ == "__main__": print OvmHost.getAllVms()