#!/u:sr/bin/env python
#coding=utf-8
#edite  panwang
import docker
import sys
import  requests
import json
import queue
import threading
from aliyunsdkcore import client
from aliyunsdkess.request.v20140828.DescribeScalingInstancesRequest import DescribeScalingInstancesRequest
from aliyunsdkecs.request.v20140526.DescribeNetworkInterfacesRequest import DescribeNetworkInterfacesRequest
from aliyunsdkcore.request import CommonRequest
from aliyunsdkecs.request.v20140526.DescribeInstancesRequest import DescribeInstancesRequest
from aliyunsdkslb.request.v20140515.DescribeLoadBalancerAttributeRequest import DescribeLoadBalancerAttributeRequest
import time


AccessKey = 'LTAIuPbTPL3LDDKN'
AccessSecret = 'ORcNedKwWuwVtcq4IRFtUDZgS0b1le'
RegionId = 'cn-hangzhou'
clt = client.AcsClient (AccessKey, AccessSecret, RegionId)
#stress
#slb_id = 'lb-bp12usgpoh04qsa6pw42r'
#longvidleoapi
id_1 = 'lb-bp1d6hp2ctotgt870miav'
id_2 = 'lb-bp1lktzqe3mksoj8whjdf'

class MyThread (threading.Thread):
    def __init__(self, func):
        threading.Thread.__init__ (self)
        
        self.func = func

    def run(self):
        self.func ()

#健康检查
def  checkHealth(ipadd):
    while  True:
        health_url = 'http://%s:8182/longvideoapi/test' %(ipadd)
        header = {"Content-Type":"application/json"}
        try:
            health_code = requests.get(health_url).status_code
        except  Exception  as  e:
           continue
        if  health_code == 200:
            return  False
            
#服务更新完之后逐步修改服务器的权重值，直接加载100会出现502。权重值每次增加10，每2s修改一次
def setInstanceWeightProcess(instance_id):
    for  i in range(1,6):
        weight = i*20
        setWeight(id_1,instance_id,weight)
        setWeight(id_2,instance_id,weight)
        time.sleep(5)

#设置权重 instance_id :服务器id，weight：权重值
def setWeight(slb_id,instance_id ,weight):

    BackendServers = [{"ServerId": instance_id, "Weight": weight}]

    request = CommonRequest ()
    request.set_accept_format ('json')
    request.set_domain ('slb.aliyuncs.com')
    request.set_version ('2014-05-15')
    request.set_method ('POST')
    request.set_action_name ('SetBackendServers')
    request.add_query_param ('BackendServers', BackendServers)
    request.add_query_param ('LoadBalancerId', slb_id)
    try:
        response = clt.do_action (request)
    except Exception as e:
        print (e)
#获取slb下所有服务器信息
def  getInstanceId(slb_id):
    request = DescribeLoadBalancerAttributeRequest()
    request.set_accept_format('json')
    request.set_LoadBalancerId(slb_id)
    response = clt.do_action_with_exception(request)
    return json.loads (response)

#获取实例IP地址
def  getIpadd(instance_id):
    request = DescribeNetworkInterfacesRequest()
    request.set_accept_format('json')
    request.set_InstanceId(instance_id)
    response = clt.do_action_with_exception(request)
    request_content = json.loads(response)
    IpAddr  = request_content['NetworkInterfaceSets']['NetworkInterfaceSet'][0]['PrivateIpAddress']
    return  IpAddr

#更新服务
def  update():
    time.sleep(10)
    global success_count
    apps = 'vlogapi'
    version = sys.argv[1]
    registry = 'registry-vpc.cn-hangzhou.aliyuncs.com/stuuudy/vlogapi:{}'.format(version)
    while  not q2.empty():
        instance_id = q2.get()
        ipadd = getIpadd(instance_id)
        print("服务器信息：" + "%s/%s" %(instance_id, ipadd))
        client = docker.DockerClient(base_url='tcp://%s:2375'  %(ipadd),timeout=60 )
        try:
        #更新前移除旧的容器
            id = client.containers.get(apps)
            id.remove(force = True)

        except Exception as e:
            print("容器不存在或者无法删除当前容器")
        try:
            #更新前删除旧的镜像
            images = client.images.list(all)
            
            for  i in range(len(images)):
              if images[i]:
                 client.images.remove(force=True, image=images[i].tags[0])
                 time.sleep(2)
            #images = client.images.get(registry)
            #client.images.remove(force=True, image=registry)
        except Exception as e:
            print(e)
            print("镜像不存在，无法获取到镜像ID")
            sys.exit(0)
        try:
            #登录镜像仓库
            client.login(username='stuuudys' ,password='Qingqu@2019', registry='registry-vpc.cn-hangzhou.aliyuncs.com')
            #启动一个容器
            client.containers.run(registry, detach = True, cap_add = 'SYS_PTRACE', network_mode = 'host', name = apps,volumes={'/datalog/': {'bind': '/datalog/', 'mode': 'rw'}})
            checkHealth(ipadd)
            print("%s ：权重修改中......" %(ipadd))

            setInstanceWeightProcess(instance_id)
            success_count = success_count + 1
            print("更新进度" + "%s/%s"  %(success_count, total))
        except Exception as e:
            raise e
            sys.exit()#容器启动失败立即退出更新

if __name__ == '__main__':


    #更新完成计数
    success_count = 0
    threads = []
    thread_num = 1
    res = getInstanceId (id_1)
    #slb下服务器总数
    total = len(res["BackendServers"]["BackendServer"])
    q1 = queue.Queue()
    q2 = queue.Queue()
    if res["BackendServers"]["BackendServer"]:
        for i in range ((len (res["BackendServers"]["BackendServer"]))):
            instance_id = res["BackendServers"]["BackendServer"][i]["ServerId"]
            q1.put(instance_id)            

    while not  q1.empty():
        for i in range (thread_num ):
            if q1.empty():
               break
            instance_id = q1.get ()
            setWeight (id_1,instance_id, 0)
            setWeight (id_2,instance_id, 0)

            q2.put(instance_id)
        for i in range (thread_num ):
        # 开启线程
            thread = MyThread (update)
            thread.start ()
            threads.append(thread)
        for thread in threads:
            thread.join ()
    

