blob: 3c61500630d7aef191c5cc95d41a5be784740748 [file] [log] [blame]
# Licensed to the Apache Software Foundation (ASF) under one
# or more contributor license agreements. See the NOTICE file
# distributed with this work for additional information
# regarding copyright ownership. The ASF licenses this file
# to you under the Apache License, Version 2.0 (the
# "License"); you may not use this file except in compliance
# with the License. You may obtain a copy of the License at
#
# http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing,
# software distributed under the License is distributed on an
# "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
# KIND, either express or implied. See the License for the
# specific language governing permissions and limitations
# under the License.
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():
def scanStoppedVmOnPrimaryStorage(vms):
def isMyVmDirLink(path):
return (islink(path) and exists(join(path, 'vm.cfg')) and ('-' in basename(path)) and (exists(join(path, makeOwnerFileName()))))
mps = OvmStoragePool()._getAllMountPoints()
for mountPoint in mps:
runningPool = join(mountPoint, 'running_pool')
if not exists(runningPool):
logger.debug(OvmHost.getAllVms, "Primary storage %s not existing, skip it. this should be first getAllVms() called from Ovm resource configure"%runningPool)
continue
for dir in os.listdir(runningPool):
vmDir = join(runningPool, dir)
if not isMyVmDirLink(vmDir):
logger.debug(OvmHost.getAllVms, "%s is not our vm directory, skip it"%vmDir)
continue
if vms.has_key(dir):
logger.debug(OvmHost.getAllVms, "%s is already in running list, skip it"%dir)
continue
logger.debug(OvmHost.getAllVms, "Found a stopped vm %s on primary storage %s, report it to management server" % (dir, mountPoint))
vms[dir] = "DOWN"
try:
l = OvmHost()._getAllDomains()
dct = {}
host = OvmHost()
for name, id in l:
try:
vmPath = host._getVmPathFromPrimaryStorage(name)
vmStatus = db_get_vm(vmPath)
dct[name] = vmStatus['status']
except Exception, e:
logger.debug(OvmHost.getAllVms, "Cannot find link for %s on primary storage, treat it as Error"%name)
dct[name] = 'ERROR'
scanStoppedVmOnPrimaryStorage(dct)
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('<timestamp>').rstrip('</timestamp>')
# 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()