#!/usr/bin/env python
#-*-coding:UTF-8-*-
"""
@Item   :  IO Ctl
@Author :  Villiam Sheng
@Group  :  Python DEV Group
@Date   :  2013-05-29
@Funtion:
        CPU control:
                To control for CPU
"""
import os,sys,time , libvirt , traceback,commands
'''
    Func : Record error message
        path :  Message save path
        formats : Record message time formata
        log_name : Message file name
        itme :  function error
        info :  Error / info information
'''
def oper_log(log_name,item,info):
    path  = '/tmp/'
    stime = time.strftime('%Y-%m-%d %H:%M:%S')
    formats= '[%s] %s:: %s \n' % (stime,item,info)
    if not os.path.exists(path):
        os.mkdir(path)
    try:
        if log_name.split('.')[1] == 'log':
            fp = open(path + log_name,'a')
        elif log_name.split('.')[1] == 'info':
            fp = open(path + log_name,'w')
        else:
            fp = open(path + log_name,'a')
        fp.write(formats)
        fp.close()
    except Exception,e:
        pass
class cpuctl(object):
    def __init__(self):
        self.conn = libvirt.open(None)
    def _VmsCPUPercent(self,uuid):
        '''
        Func info : Calculation virtual machine of CPU percentage , if error , return 0
            uuid : instance uuid
            cycle_time : 10s
            cpuTimeStart:  virtual machine cpu running time
            nr_cores :  CPU number all
            Formula to calculate:
                    %CPU = 100 × cpu_time_diff / (t × nr_cores × 1e9)
        '''
        try:
            nr_cores =  self.conn.getInfo()[2]
            cpuTimeStart =  self.conn.lookupByID(uuid).info()[-1]
            sysTimeStart = time.time()
            time.sleep(1)
            cpuTimeEnd = self.conn.lookupByID(uuid).info()[-1]
            sysTimeEnd = time.time()
            cpuTimeDiff = cpuTimeEnd - cpuTimeStart
            sysTimeDiff = sysTimeEnd - sysTimeStart
            return 100 * cpuTimeDiff / ( sysTimeDiff * 1 * 1e9)
        except Exception,e:
            oper_log('cpuctl.log','_cpuPercent','ID : %s Error : %s'%(uuid,e))
            return 0
    def _isHostUpload(self):
        '''
        Func info : Return kvm host the current system load every 1 minute
            if error , return 0
        '''
        try:
            return float(os.popen('uptime').read().split(':')[-1].strip()[:4])
        except:
            oper_log('cpuctl.log','_isUpload',traceback.format_exc())
            return 0
    def _operRate(uuid):
        try:
            x,y  = commands.getstatusoutput('virsh dumpxml %s' %uuid)
            print x,y
        except:
            LOG.error(traceback.format_exc())
    def _isHostCPUFreePercent(self):
        ''''
        Func info : Return kvm host CPU free percent . Go to 2 times every 3 seconds, get the average CPU idle percentage
            if error , return 0
        '''
        try:
            return float(os.popen('sar 3 3 ').readlines()[-1].split()[-1])
        except:
            oper_log('cpuctl.log','_isCPUFreePercent',traceback.format_exc())
            return 0
    def _isHostCPUNum(self):
        try:
            pass
        except:
            return 0
    def _isVMScpuNum(self,uuid):
        '''
        Func info : Return virtual machine cpu number
            if error ,return 1
        '''
        try:
            return self.conn.lookupByID(uuid).info()[-2]
        except:
            oper_log('cpuctl.log','isVMScpuNum',traceback.format_exc())
            return 1
    def work(self):
        '''
        Working func :  .....
            vms_list : Getting all virtual machine ID
            self._VmsCPUPercent() : Return cpu percent ...
            self._isUpload()   : Return kvm host loads one s
            sefl._isCPUFreePercent: Return kvm host cpu free percent
            loadValues : KVM HOST Default load values
        '''
        hostPercen = self._isHostCPUFreePercent()
        loadValues = 49
        print hostPercen
        vms_list = self.conn.listDomainsID()
        if  self._isHostUpload() <= loadValues:
            for i in vms_list:
                if  self._VmsCPUPercent(i) <= 99.0:
                    print self.conn.lookupByID(i).name()
                    print self._isVMScpuNum(i)
                else:
                    print 'ot'
        else:
            print 'no upload'
if __name__ == "__main__":
    st = cpuctl()
    st.work()