#!/usr/bin/env python
# coding=utf-8

import requests
import json
from time import sleep
from os import system
import os
from threading import Thread
from logger.logrecord import LogRecord
from copy import deepcopy
import sys

if os.name == 'posix' and sys.version_info[0] < 3:
    import subprocess32 as subprocess
else:
    import subprocess


class VirtMachine(object):
    __vm = None

    def __init__(self, vmInfo, usrInfo, ip_port, httpStyle="http"):

        self.__userInfo = usrInfo

        self.__url = httpStyle + "://" + ip_port
        self.__ip_port = ip_port
        self.__vmInfo = deepcopy(vmInfo)
        self.__vm = None

        self.__passwd       = None
        self.__enterVM_falg = False
        self.__certificateDir = "/mcos/dvclient/cfg/.smep"  # 证书目录

    def vmIsUsed(self):  # 查询状态

        if self.__vm == None:
            return False
        if self.__vm.poll() == None:
            LogRecord.instance().logger.debug(" ---------- self.__vm.poll() == None -----------")
            return True
        else:
            return False


    def downloadCertificate(self, certificateDir=None):
        if certificateDir == None:
            # cmd = "wget -t 1 -T 3 -O /mcos/dvclient/cfg/.smep/%s.pem  %s/api/downloadcert/%s" % (self.__vmInfo["vmId"],self.__url,self.__vmInfo["vmId"])
            cmd = "wget -t 1 -T 3 -O %s/%s.pem  %s/api/downloadcert/%s" % (
                self.__certificateDir, self.__vmInfo["vmId"], self.__url, self.__vmInfo["vmId"])

        else:
            # cmd = "wget -t 1 -T 3 -O %s/%s.pem  %s/api/downloadcert/%s" % (certificateDir,self.__vmInfo["vmId"],self.__url,self.__vmInfo["vmId"])
            cmd = "wget -t 1 -T 3 -O %s/%s.pem  %s/api/downloadcert/%s" % (
                self.__certificateDir, self.__vmInfo["vmId"], self.__url, self.__vmInfo["vmId"])

        if not os.path.exists(self.__certificateDir):  # 如果 不存在，则新建目录
            system("mkdir -p " + self.__certificateDir)

        # try:
        #     # 删除  证书
        #     cmd2 = "rm  %s/%s.pem" % (self.__certificateDir,self.__vmInfo["vmId"])
        #     LogRecord.instance().logger.debug("删除旧证书 :  " + cmd2)
        #     system(cmd2)
        # except Exception as e:
        #     print "删除旧证书 异常"

        # 需要判断证书 是否能用  为空
        status = system(cmd)

        if status != 0:  # 抛 wget下载异常
            LogRecord.instance().logger.error("下载证书失败！-- %s " % self.__vmInfo["vmId"])
            return False
        else:
            return True

    # 更新虚拟机信息
    def vmInfoUpdate(self, vmInfo=None):
        if vmInfo != None:
            self.__vmInfo["osStatus"] = deepcopy(vmInfo["osStatus"])
            self.__vmInfo["vmIp"] = deepcopy(vmInfo["vmIp"])
            self.__vmInfo["hostId"] = deepcopy(vmInfo["hostId"])
            self.__vmInfo["vmPort"] = deepcopy(vmInfo["vmPort"])
            self.__vmInfo["guestAddress"] = deepcopy(vmInfo["guestAddress"])

    # -------------------------------------------------------
    #  功能 ： 获取 虚拟机 列表 解  析
    # -------------------------------------------------------
    def __vmInfo_analysis(self, result):

        vmInfo = {"type": "",
                  "name": "",
                  "vmId": "",
                  "osType": "",
                  "osStatus": "",
                  "vmIp": "",
                  "vmPort": "",
                  "vmPassWd": "",
                  "vmDomain": "",
                  "guestAddress": [],
                  "hostId": None
                  }
        dictVms = result
        vmInfo["name"] = dictVms["name"]
        vmInfo["vmId"] = dictVms["id"]
        vmInfo["osType"] = dictVms['os']["type"]
        vmInfo["osStatus"] = dictVms["status"]["state"]
        if dictVms['display'].has_key("address"):
            vmInfo["type"] = dictVms['display']["type"]
            vmInfo["vmIp"] = dictVms['display']["address"]
            vmInfo["vmPort"] = dictVms['display']["securePort"]

        if dictVms['host'] != None:  # 关机状态   dictVms['host'] == None
            if dictVms['host']["id"] != None:
                vmInfo["hostId"] = dictVms['host']["id"]

        if dictVms['guestInfo'] != None:  # 虚拟机网卡
            if dictVms['guestInfo']["ips"] != None:
                if dictVms['guestInfo']["ips"]["ips"] != None:
                    addresslist = dictVms['guestInfo']["ips"]["ips"]
                    for i in range(len(addresslist)):
                        vmInfo["guestAddress"].append(addresslist[i]["address"])

        if dictVms['display']['certificate'] == None:
            vmInfo["vmDomain"] = None
        else:
            vmDomain = dictVms['display']['certificate']["subject"]
            tmp, vmInfo["vmDomain"] = vmDomain.split("CN=", 2)
        vmInfo["osType"] = dictVms["os"]["type"]

        return vmInfo

    def getSingleVMInfo(self):
        recv = None
        try:
            recv = requests.get("%s/api/vitualMachine/vms/%s" % (self.__url, self.__vmInfo["vmId"]), timeout=10)
            recv.raise_for_status()  # 如果响应状态码不是 200，就主动抛出异常
            # 判断 是否是 json类型
            if recv.headers['content-type'] != "application/json;charset=UTF-8":
                raise Exception(" content-type err %s ; not is  application/json" % recv.headers['content-type'])

            # print recv.text
            dict_tmp = recv.json()["result"]
            if dict_tmp == None:
                raise Exception("recv.json()[\"result\"] == None")

            status = dict_tmp["status"]
            info = dict_tmp["info"].encode('utf-8')

            if status != "y":
                LogRecord.instance().logger.error(info)
                return False, info
            vmInfo = self.__vmInfo_analysis(dict_tmp["result"])
            return True, vmInfo

        except requests.exceptions.ConnectionError as e:
            LogRecord.instance().logger.exception("获取单个虚拟机信息失败")
            return False, "获取单个虚拟机信息,网络连接错误"

        except requests.exceptions.Timeout as e:
            LogRecord.instance().logger.exception("获取虚拟机信息,网络超时")
            return False, "获取虚拟机信息,网络超时"

        except Exception:
            LogRecord.instance().logger.exception("获取单个虚拟机信息失败")
            return False, "获取单个虚拟机信息异常"

    def vmInfoShow(self):

        # print "-----"
        # for key in self.__vmInfo.keys():
        #     print "%s  : [%s] " % (key ,self.__vmInfo[key])
        # print "-----"

        info = "\n"
        for key in self.__vmInfo.keys():
            str_info = "    %s  : [%s] \n" % (key, self.__vmInfo[key])
            info = info + str_info
        LogRecord.instance().logger.debug(info + "\n")

    # -----------------------------------
    # 功能  ：  开启虚拟机
    # ----------------------------------
    def VMPowerOn(self):
        # print "VMPowerOn---",
        url = '%s/api/vms/%s/operate' % (self.__url, self.__vmInfo["vmId"])
        payload = {
            "login": self.__userInfo["userName"],
            "password": self.__userInfo["userPassword"],
            "operateType": "start"}
        try:
            headers = {'content-type': 'application/json'}
            recv = requests.post(url, data=json.dumps(payload), headers=headers, timeout=3)

            if recv.status_code != 200:
                raise Exception("Http error %s" % recv.status_code)
            if recv.headers['content-type'] != "application/json;charset=UTF-8":
                LogRecord.instance().logger.error(recv.headers['content-type'])
                LogRecord.instance().logger.error(recv.text)
                raise Exception(" content-type not is  application/json")

            dict_tmp = recv.json()["result"]
            if dict_tmp == None:
                raise Exception("recv.json()[\"result\"] == None")

            if dict_tmp["status"] == "y":
                return True, ""
            else:
                LogRecord.instance().logger.error("虚拟机开机错误:%s" % str(dict_tmp["info"]))
                return False, dict_tmp["info"]

        except requests.exceptions.ConnectionError as e:
            LogRecord.instance().logger.exception("虚拟机开机,网络连接错误")
            return False, "虚拟机无法开机,网络连接错误"
        except requests.exceptions.Timeout as e:
            LogRecord.instance().logger.exception("虚拟机开机,网络超时")
            return False, "虚拟机无法开机,网络超时"

        except Exception as e:
            LogRecord.instance().logger.exception("开机异常")
            return False, "开机异常"

    # -----------------------------------
    # 功能  ：  关闭虚拟机
    # 失败 抛异常
    # -----------------------------------
    def VMShutdown(self):
        url = '%s/api/vms/%s/operate' % (self.__url, self.__vmInfo["vmId"])
        payload = {
            "login": self.__userInfo["userName"],
            "password": self.__userInfo["userPassword"],
            "operateType": "shutdown"}
        try:
            headers = {'content-type': 'application/json'}
            recv = requests.post(url, data=json.dumps(payload), headers=headers, timeout=5)

            recv.raise_for_status()  # 如果响应状态码不是 200，就主动抛出异常
            if recv.headers['content-type'] != "application/json;charset=UTF-8":
                raise Exception(" content-type not is  application/json")

            dict_tmp = recv.json()["result"]
            if dict_tmp == None:
                raise Exception("recv.json()[\"result\"] == None")
            print dict_tmp
            if dict_tmp["status"] == "y":
                return True, ""
            else:
                return False, dict_tmp["info"]

        except requests.exceptions.ConnectionError as e:
            LogRecord.instance().logger.exception("虚拟机关机,网络连接错误")
            return False, "虚拟机关机,网络连接错误"
        except requests.exceptions.Timeout as e:
            LogRecord.instance().logger.exception("虚拟机关机,网络超时")
            return False, "虚拟机关机,网络超时"
        except Exception as e:
            LogRecord.instance().logger.exception("关机")
            return False, "关机异常"



    # -----------------------------------
    # 功能  ：  断电虚拟机
    # -----------------------------------
    def VMPoweroff(self):
        url = '%s/api/vms/%s/operate' % (self.__url, self.__vmInfo["vmId"])
        payload = {
            "login": self.__userInfo["userName"],
            "password": self.__userInfo["userPassword"],
            "operateType": "stop"}
        try:
            headers = {'content-type': 'application/json'}
            recv = requests.post(url, data=json.dumps(payload), headers=headers, timeout=5)

            recv.raise_for_status()  # 如果响应状态码不是 200，就主动抛出异常
            if recv.headers['content-type'] != "application/json;charset=UTF-8":
                raise Exception(" content-type not is  application/json")

            dict_tmp = recv.json()["result"]
            if dict_tmp == None:
                raise Exception("recv.json()[\"result\"] == None")
            print dict_tmp
            if dict_tmp["status"] == "y":
                return True, ""
            else:
                return False, dict_tmp["info"]

        except requests.exceptions.ConnectionError as e:
            LogRecord.instance().logger.exception("虚拟机关机,网络连接错误")
            return False, "虚拟机关机,网络连接错误"
        except requests.exceptions.Timeout as e:
            LogRecord.instance().logger.exception("虚拟机关机,网络超时")
            return False, "虚拟机关机,网络超时"
        except Exception as e:
            LogRecord.instance().logger.exception("关机")
            return False, "关机异常"

    # -----------------------------------
    # 功能  ： 重启虚拟机
    # ----------------------------------
    def VMReboot(self):

        url = '%s/api/vms/%s/operate' % (self.__url, self.__vmInfo["vmId"])
        payload = {
            "login": self.__userInfo["userName"],
            "password": self.__userInfo["userPassword"],
            "operateType": "reboot"}
        try:
            headers = {'content-type': 'application/json'}
            recv = requests.post(url, data=json.dumps(payload), headers=headers, timeout=2)

            recv.raise_for_status()  # 如果响应状态码不是 200，就主动抛出异常
            if recv.headers['content-type'] != "application/json;charset=UTF-8":
                LogRecord.instance().logger.error(recv.headers['content-type'])
                raise Exception(" content-type not is  application/json")

            dict_tmp = recv.json()["result"]
            if dict_tmp == None:
                raise Exception("recv.json()[\"result\"] == None")

            if dict_tmp["status"] == "y":
                return True, ""
            else:
                return False, dict_tmp["info"]

        except requests.exceptions.ConnectionError as e:
            LogRecord.instance().logger.error("虚拟机重启,网络连接错误", str(e.message))
            return False, "虚拟机重启,网络连接错误"
        except requests.exceptions.Timeout as e:
            LogRecord.instance().logger.error("虚拟机重启,网络超时: " + str(e.message))
            return False, "虚拟机重启,网络超时"
        except Exception as e:
            LogRecord.instance().logger.exception("异常")
            return False, "重启异常"

    # --------------------------------------------------------
    # 功能  ：  获取域名
    #
    # --------------------------------------------------------
    def getSpiceDomain(self):

        if self.__vmInfo["hostId"] == None:
            msg = "%s 虚拟机hostId为空,不可用" % str(self.__vmInfo["vmId"])
            LogRecord.instance().logger.debug(msg)
            return False, msg

        url = "%s/api/vitualMachine/vms/%s/%s" % (self.__url, self.__vmInfo["vmId"], self.__vmInfo["hostId"])  #
        # url = "http://192.168.102.33:8080/api/vitualMachine/vms/d36d1c2a-21b7-40f9-8415-7529aaeb47da/bd5a4afe-d440-477f-afd1-33b95d55daa0"
        # LogRecord.instance().logger.debug("getSpiceDomain : %s " % url)
        recv = None
        try:
            recv = requests.get(url, timeout=3)

            recv.raise_for_status()  # 如果响应状态码不是 200，就主动抛出异常
            # 判断 是否是 json类型
            if recv.headers['content-type'] != "application/json;charset=UTF-8":
                # print recv.headers['content-type']
                raise Exception(" content-type err %s ;not is  application/json" % recv.headers['content-type'])
            # print recv.text
            dict_tmp = recv.json()["result"]
            status = dict_tmp["status"]
            info = dict_tmp["info"].encode('utf-8')

            if dict_tmp == None:
                LogRecord.instance().logger.debug("获取虚拟机server域异常：None")
                return False, "获取虚拟机server域异常：None"
            if status != "y":
                LogRecord.instance().logger.debug(info)
                return False, info

            try:
                result = dict_tmp["result"]
                for key in result.keys():
                    if key == "address":
                        tmp = " %s : %s \n" % (key, result[key])
                        LogRecord.instance().logger.debug(tmp + "\n")

                domainName = result["address"].encode('utf-8')
                LogRecord.instance().logger.debug("请求域名:" + str(domainName))
                return True, domainName   # 返回 域名

            except Exception as e:
                raise e

        except requests.exceptions.ConnectionError as e:
            LogRecord.instance().logger.error("获取虚拟机server域域名,网络连接异常," + str(e.message))
            return False, "获取虚拟机server域域名,网络链接异常"
        except requests.exceptions.Timeout as e:
            LogRecord.instance().logger.error("获取虚拟机server域异常,网络超时: " + str(e.message))
            return False, "获取server域名,网络超时"
        except Exception as e:
            LogRecord.instance().logger.exception("异常")
            return False, "获取虚拟机server域异常常"

    # --------------------------------------------------------
    # 功能  ：  获取sever ip
    # --------------------------------------------------------
    #
    #   GET
    #   http://192.168.102.33:8080/api/vitualMachine/vms/{vmId}/{hostId}/nics
    #
    #   返回：
    #     {
    #         "result"  : {
    #             "status" : "y"
    #             "info"   : ""
    #             "result" : {
    #                 "hostNics" [
    #                     {
    #                         "name"    :"enp3s0"  ,
    #                         "bridged" : "true",
    #                         "status"  :  {'state' : 'up',  ...}  ,
    #                         "ip"      :{  'setGateway'  : True,
    #                                       'netmask'     : '255.255.255.0',
    #                                       'address'     : '192.168.102.27',
    #                                       'setAddress'  : True,
    #                                       'gateway'     : '192.168.102.254',
    #                                       'setNetmask'  : True }
    #                     }
    #                       ......
    #                       ......
    #                     {
    #                         "name"    :"enp3s0"  ,
    #                         "bridged" : "true",
    #                          "status" :  {'state' : 'down',...}  ,
    #                          "ip" :{'setGateway'  : False,
    #                                 'netmask'     : '',
    #                                 'address'     : '',
    #                                 'setAddress'  : True,
    #                                 'gateway'     : '',
    #                                 'setNetmask'  : True}
    #                     }
    #                   ]
    #
    #             }
    #         }
    # --------------------------------------------------------
    def getSpiceServerIp(self):

        if self.__vmInfo["hostId"] == None:
            msg = "虚拟机hostId为空,不可用  %s " % str(self.__vmInfo["vmId"])
            LogRecord.instance().logger.debug(msg)
            return False, msg

        url = "%s/api/vitualMachine/vms/%s/%s/nics" % (self.__url, self.__vmInfo["vmId"], self.__vmInfo["hostId"])  #
        LogRecord.instance().logger.debug("getSpiceServerIp : %s " % url)
        recv = None
        try:
            recv = requests.get(url, timeout=3)

            recv.raise_for_status()  # 如果响应状态码不是 200，就主动抛出异常
            # 判断 是否是 json类型
            if recv.headers['content-type'] != "application/json;charset=UTF-8":
                # print recv.headers['content-type']
                raise Exception(" content-type err %s ;not is  application/json" % recv.headers['content-type'])
            # print recv.text
            dict_tmp = recv.json()["result"]
            status = dict_tmp["status"]
            # info    = dict_tmp["info"]
            info = str(dict_tmp["info"].encode('utf-8'))

            if dict_tmp == None:
                LogRecord.instance().logger.debug("获取虚拟机server Ip 异常：None")
                return False, "获取虚拟机server Ip异常：None"
            if status != "y":
                LogRecord.instance().logger.debug(info)
                return False, info

            # --------------------  解析 --------------------------------

            serverNetWorkInfoList = []
            try:
                result = dict_tmp["result"]
                for key in result.keys():
                    if key == "hostNics":
                        hostNics = result[key]


                        for i in range(len(hostNics)):  # 遍历列表
                            serverNetWorkInfo = {
                                "name": "",
                                'address': "",
                                "state": "down",
                                "bridged": "False"
                            }

                            for key in hostNics[i].keys():
                                if key == "name":
                                    serverNetWorkInfo["name"] = hostNics[i][key]
                                    # tmp =  " %s : %s \n" % (key,hostNics[i][key])
                                    # LogRecord.instance().logger.debug(tmp + "\n")
                                if key == "status":
                                    status = hostNics[i][key]
                                    for key in status.keys():
                                        if key == "state":
                                            serverNetWorkInfo["state"] = status[key]
                                            # tmp =  " %s : %s \n" % (key,status[key])
                                            # LogRecord.instance().logger.debug(tmp + "\n")
                                if key == "ip":
                                    ip = hostNics[i][key]
                                    for key in ip.keys():
                                        if key == "address":
                                            serverNetWorkInfo["address"] = ip[key].encode("utf-8")
                                            # tmp =  " %s : %s \n" % (key,ip[key])
                                            # LogRecord.instance().logger.debug(tmp + "\n")
                                if key == "bridged":
                                    serverNetWorkInfo["bridged"] = hostNics[i][key]
                                    # tmp =  " %s : %s \n" % (key,hostNics[i][key])
                                    # LogRecord.instance().logger.debug(tmp + "\n")

                            serverNetWorkInfoList.append(serverNetWorkInfo)

                            # print "------ ----------- ------- ---------- ----- ---- "
                # print serverNetWorkInfoList

                res = [False, "没有可用的ip"]
                for i in range(len(serverNetWorkInfoList)):
                    if serverNetWorkInfoList[i]["bridged"] == True and \
                                    serverNetWorkInfoList[i]["state"] == 'up':
                        res[0] = True
                        res[1] = serverNetWorkInfoList[i]["address"]

                LogRecord.instance().logger.info("请求serverIp:" + str(res[1]))
                return res  # 返回 域名

            except Exception as e:
                raise e

        except requests.exceptions.ConnectionError as e:
            LogRecord.instance().logger.error("获取虚拟机server Ip 网络连接异常 : " + str(e.message))
            return False, "获取虚拟机server Ip 网络连接异常"
        except requests.exceptions.Timeout as e:
            LogRecord.instance().logger.error("获取虚拟机server Ip,网络超时: " + str(e.message))
            return False, "获取虚拟机server Ip,网络超时"
        except Exception as e:
            LogRecord.instance().logger.exception("获取虚拟机server Ip 异常")
            return False, "获取虚拟机server Ip 异常常"

    ##--------------------------------------------------------------
    # 获取虚拟机密码
    ##------------------------------------------------------------
    def getVMPasswd(self):

        # 1. 先获取虚拟机状态
        res = self.getSingleVMInfo()
        if res[0] == False:
            LogRecord.instance().logger.error(res[1])
            return False, "获取虚拟机状态失败"
        else:
            vmInfo = res[1]

        # 2. 根据虚拟机状态 ，判断下一步操作，
        #   down     -->  进行 启动。。。 等待 powering_up   up
        #   [ down   powering_up  up  powering_down  wait_for_launch   reboot_in_progress ]
        if vmInfo["osStatus"] == "powering_down":  # 如果是关机进行中
            return False, "powering_down", "plase watting...."

        elif not vmInfo["osStatus"] in ["up", "powering_up"]:
            self.VMPowerOn()  # 开机
            try:
                cnt = 0
                errCnt = 0
                while True:
                    res = self.getSingleVMInfo()
                    if res[0] == False:
                        errCnt = errCnt + 1
                        if errCnt > 3:
                            return False, "获取虚拟机状态失败"
                    else:
                        errCnt = 0
                        vmInfo = res[1]
                    sleep(0.1)
                    cnt = cnt + 1
                    LogRecord.instance().logger.debug(" watting powering up!")
                    if vmInfo["osStatus"] == "up" or cnt > 300:
                        break
                    elif vmInfo["osStatus"] == "powering_up":
                        break
            except Exception as e:
                # info = "获取密码,查询状态失败 : %s" % str(e.message)
                LogRecord.instance().logger.exception("获取密码,查询状态失败")
                return False, "获取密码,查询状态失败"
        # -------------------------------------------------



        # -------------------------------------------------
        if self.__vmInfo["vmId"] == "":
            LogRecord.instance().logger.error("getVMPasswd  vmId == Null")
            return False, ""

        url = "%s/api/vms/%s/ticket" % (self.__url, self.__vmInfo["vmId"])

        # 用户信息
        payload = {
            "displayName": "xxxx",
            "inDomain": "false",
            "login": self.__userInfo["userName"],
            "password": self.__userInfo["userPassword"],
        }
        try:
            headers = {'content-type': 'application/json'}
            recv = requests.post(url, data=json.dumps(payload), headers=headers, timeout=15)
            # 判断 是否是 json类型
            if recv.headers['content-type'] != "application/json;charset=UTF-8":
                # print recv.headers['content-type']
                raise Exception("getVMPasswdErr")
            if recv.status_code != 200:
                raise Exception("Http error %s" % recv.status_code)

            dict_tmp = recv.json()["result"]

            if dict_tmp == None:
                raise Exception("getVMPasswdErr")

            status = dict_tmp["status"]  # 状态
            info = dict_tmp["info"]  # 信息
            result = dict_tmp['result']

            if status != "y":
                LogRecord.instance().logger.error(info)
                return False, info
            password = result['value']
            return True, password

        except requests.exceptions.ConnectionError as e:
            LogRecord.instance().logger.error("获取虚拟机密码 网络连接异常 : " + str(e.message))
            return False, "获取虚拟机密码 网络连接异常"
        except requests.exceptions.Timeout as e:
            LogRecord.instance().logger.error("获取虚拟机密码,网络超时: " + str(e.message))
            return False, "获取虚拟机密码,网络超时"

        except Exception as e:
            LogRecord.instance().logger.exception("获取虚拟机密码,异常")
            return False, "获取虚拟机密码,异常"

    # ---------------------------------------
    #   获取动态密码
    def enterVM(self):  #

        ##-----------------------------------------------
        if self.__vmInfo["vmIp"] == None:
            res = self.getSpiceServerIp()  # 获取 server ip
            if res[0] == False:
                return res
            self.__vmInfo["vmIp"] = res[1]

        if self.__vmInfo["vmDomain"] == None:
            res = self.getSpiceDomain()  # 获取  域名
            if res[0] == False:
                return res
            self.__vmInfo["vmDomain"] = res[1]
        ##----------------------------------------------------------


        from domainMap import DomainMap
        domain = DomainMap()
        domain.addDomainMap(self.__vmInfo["vmIp"], self.__vmInfo["vmDomain"])

        status = [True, ""]

        res = self.getVMPasswd()
        if res[0] == True:
            psswd = res[1]
            LogRecord.instance().logger.info("enterVM password =  %s ", psswd)
        else:
            LogRecord.instance().logger.exception("请求虚拟机,密码失败")
            return False, "请求虚拟机,密码失败"

        def FuncQueuGet():

            try:
                status[1] = "失败"
                self.__enterVM_falg = True
                # CenterConnectAPI.setSessionState_loged(self.__userInfo)  # 标记登录

                from os import environ  # 环境变量
                # environ["LD_LIBRARY_PATH"] = "/mcos/dvclient/lib/"

                # cmd = "window --spice-ca-file=/mcos/dvclient/cfg/.smep/smep_ca.pem   "

                # cmd = "window --spice-ca-file=%s/%s.pem   " % (self.__certificateDir,self.__vmInfo["vmId"])
                cmd = "window --spice-ca-file=%s/%s.pem   " % (self.__certificateDir, self.__vmInfo["vmId"])

                cmd = cmd + " spice://%s/?tls-port=%s\&password=%s  " % (
                    self.__vmInfo["vmDomain"], self.__vmInfo["vmPort"], psswd)
                # cmd = cmd + " spice://%s/?tls-port=%s\&password=%s  " % (self.__vmInfo["vmIp"], self.__vmInfo["vmPort"],psswd)
                # cmd = cmd + " spice://%s/?tls-port=%s\&password=%s  " % ("server27.com", self.__vmInfo["vmPort"],psswd)

                cmd = cmd + "  -f"
                cmd = cmd + "  --spice-disable-usbredir"  # 关闭 spice usb
                LogRecord.instance().logger.info("进入虚拟机： " + cmd)
                os.system(cmd)  # 阻塞
            except Exception as e:
                # err_info = "进入虚拟机错误： %s  " % self.__vmInfo["vmId"] + e.message
                # LogRecord.instance().logger.error(err_info)
                LogRecord.instance().logger.exception("进入虚拟机错误")
            finally:
                self.__enterVM_falg = False  # 复位 进入虚拟机标志为

        # ---------------------子线程函数体 end---------------
        if self.__enterVM_falg == False:
            # 查询证书是否存在，没有则 下载证书
            if False == os.path.isdir(self.__certificateDir):  # 如果文件目录不存在，则新建目录
                os.makedirs(self.__certificateDir)

            pemPath = self.__certificateDir + "/" + self.__vmInfo["vmId"] + ".pem"

            if False == os.path.isfile(pemPath):  # 如果证书不存在，则下载证书
                self.downloadCertificate()

            threadQueueGet = Thread(target=FuncQueuGet)  # 初始化接收线程
            threadQueueGet.setDaemon(True)
            threadQueueGet.start()  # 启动接收线程
            sleep(0.02)
            print status

            return True, ""
        else:
            return True, ""

    # 打开虚拟机准备工作
    def openVmInit(self):

        ##------------------ 1 域名映射-----------------------------
        LogRecord.instance().logger.info("获取域名.... ")
        if self.__vmInfo["vmIp"] == None:
            res = self.getSpiceServerIp()  # 获取 server ip
            if res[0] == False:
                return res

            from ip_port_check import ip_check
            if ip_check(res[1]):
                self.__vmInfo["vmIp"] = res[1]
            else:
                LogRecord.instance().logger.error("vmIp格式错误:"+ str(res[1]))
                return False, "vmIp格式错误"

        if self.__vmInfo["vmDomain"] == None:
            res = self.getSpiceDomain()  # 获取  域名
            if res[0] == False:
                return res
            self.__vmInfo["vmDomain"] = res[1]
            LogRecord.instance().logger.info("获取域名  %s ", str(self.__vmInfo["vmDomain"]))
        ##----------------------------------------------------------

        from domainMap import DomainMap
        domain = DomainMap()
        domain.addDomainMap(self.__vmInfo["vmIp"], self.__vmInfo["vmDomain"])  # 添加域名映射


        # ------------  2 密码 -----------------------------
        print "获取密码"
        res = self.getVMPasswd()
        if res[0] == True:
            self.__passwd = res[1]
            LogRecord.instance().logger.info("enterVM password =  %s ", self.__passwd)
        else:
            LogRecord.instance().logger.error("请求虚拟机,密码失败")
            return False, "请求虚拟机,密码失败"


        # ----------- 3 证书 ---------------------
        print "下载证书"
        # 查询证书是否存在，没有则 下载证书
        if False == os.path.isdir(self.__certificateDir):  # 如果文件目录不存在，则新建目录
            os.makedirs(self.__certificateDir)

        ## ===============================================
        # pemPath = self.__certificateDir + "/" + self.__vmInfo["vmId"] + ".pem"
        ##---- 判断证书是否存在,判断证书是否可用
        # if False == os.path.isfile(pemPath):  # 如果证书不存在，则下载证书
        #     if self.downloadCertificate() == False:
        #         return False, "证书下载失败"
        ##------------------------------------------------
        if self.downloadCertificate() == False:  # 下载证书
            return False, "证书下载失败"
        # =================================================
        return True, ""

    # 进入虚拟机
    def openVm(self):

        args = ["window"]

        cafile = "--spice-ca-file=%s/%s.pem" % (self.__certificateDir, self.__vmInfo["vmId"])
        domain_port_passwd = "spice://%s/?tls-port=%s&password=%s" % (self.__vmInfo["vmDomain"],
                                                                      self.__vmInfo["vmPort"], self.__passwd)
        full_Screen = "-f"
        disableUsbdir = "--spice-disable-usbredir"

        args.append(str(cafile))
        args.append(str(domain_port_passwd))
        args.append(full_Screen)

        #add by pbc for usb status -top
        from common import common_run
        if common_run.usb_status == "network_ip":
            args.append(disableUsbdir)#使用usbip方式链接
        else:
            usbfilter = "--spice-usbredir-redirect-on-connect="+"0x03,-1,-1,-1,0|-1,-1,-1,-1,1"
            usbTemp = "--spice-usbredir-auto-redirect-filter="+"0x03,-1,-1,-1,0|-1,-1,-1,-1,1"
            args.append(usbfilter)
            args.append(usbTemp)
        #add by pbc for usb status -end

        # print "this is args",args
        # return

        # print args
        LogRecord.instance().logger.debug(str(args))
        try:
            self.__vm = subprocess.Popen(args, close_fds=True)  # 启动
        except Exception as e:
            info = "打开虚拟机失败:  " + str(e.message)
            LogRecord.instance().logger.exception("打开虚拟机")
            return False, "打开虚拟机失败!"

        return True, ""

    def exitVm(self):
        if self.__vm != None:
            self.__vm.kill()

            del self.__vm
            self.__vm = None


# --------------------
if __name__ == "__main__":
    pass


