<reponame>liukai0322/docklet<gh_stars>1-10
#!/usr/bin/python3

# load environment variables in the beginning
# because some modules need variables when import
# for example, userManager/model.py

# must first init loadenv
import tools, env
config = env.getenv("CONFIG")
tools.loadenv(config)

# second init logging
# must import logger after initlogging, ugly
from log import initlogging
initlogging("docklet-master")
from log import logger

import os
import http.server, cgi, json, sys, shutil
from socketserver import ThreadingMixIn
import nodemgr, vclustermgr, etcdlib, network, imagemgr, servicemgr
from userManager import userManager
import monitor
import proxytool
import guest_control, threading

import hashlib
from suds.client import Client
import requests

class DockletHttpHandler(http.server.BaseHTTPRequestHandler):
    def response(self, code, output):
        self.send_response(code)
        self.send_header("Content-type", "application/json")
        self.end_headers()
        # wfile/rfile are in byte/binary encoded. need to recode
        self.wfile.write(json.dumps(output).encode('ascii'))
        self.wfile.write("\n".encode('ascii'))
        # do not wfile.close()
        # because self.handle_one_request will call wfile.flush after calling do_*
        # and self.handle_one_request will close this wfile after timeout automatically
        # (see  /usr/lib/python3.4/http/server.py handle_one_request function)
        #self.wfile.close()

    # override log_request to not print default request log
    # we use the log info by ourselves in our style
    def log_request(code = '-', size = '-'):
        pass

    def do_PUT(self):
        self.response(400, {'success':'false', 'message':'Not supported methond'})

    def do_GET(self):
        self.response(400, {'success':'false', 'message':'Not supported methond'})

    def do_DELETE(self):
        self.response(400, {'success':'false', 'message':'Not supported methond'})

    # handler POST request
    def do_POST(self):
        global G_vclustermgr
        global G_usermgr
        #logger.info ("get request, header content:\n%s" % self.headers)
        #logger.info ("read request content:\n%s" % self.rfile.read(int(self.headers["Content-Length"])))
        logger.info ("get request, path: %s" % self.path)
        # for test
        if self.path == '/test':
            logger.info ("return welcome for test")
            self.response(200, {'success':'true', 'message':'welcome to docklet'})
            return [True, 'test ok']

        # check for not null content
        if 'Content-Length' not in self.headers:
            logger.info ("request content is null")
            self.response(401, {'success':'false', 'message':'request content is null'})
            return [False, 'content is null']

        # auth the user
        # cgi.FieldStorage need fp/headers/environ. (see /usr/lib/python3.4/cgi.py)
        form = cgi.FieldStorage(fp=self.rfile, headers=self.headers,environ={'REQUEST_METHOD':'POST'})
        cmds = self.path.strip('/').split('/')
        if cmds[0] == 'register' and form.getvalue('activate', None) == None:
            logger.info ("handle request : user register")
            username = form.getvalue('username', '')
            password = form.getvalue('password', '')
            email = form.getvalue('email', '')
            description = form.getvalue('description','')
            if (username == '' or password == '' or email == ''):
                self.response(500, {'success':'false'})
            newuser = G_usermgr.newuser()
            newuser.username = form.getvalue('username')
            newuser.password = form.getvalue('password')
            newuser.e_mail = form.getvalue('email')
            newuser.student_number = form.getvalue('studentnumber')
            newuser.department = form.getvalue('department')
            newuser.nickname = form.getvalue('truename')
            newuser.truename = form.getvalue('truename')
            newuser.description = form.getvalue('description')
            newuser.status = "init"
            newuser.auth_method = "local"
            result = G_usermgr.register(user = newuser)
            self.response(200, result)
            return [True, "register succeed"]
        if cmds[0] == 'login':
            logger.info ("handle request : user login")
            user = form.getvalue("user")
            key = form.getvalue("key")
            if user == None or key == None:
                self.response(401, {'success':'false', 'message':'user or key is null'})
                return [False, "auth failed"]
            auth_result = G_usermgr.auth(user, key)
            if  auth_result['success'] == 'false':
                self.response(401, {'success':'false', 'message':'auth failed'})
                return [False, "auth failed"]
            self.response(200, {'success':'true', 'action':'login', 'data': auth_result['data']})
            return [True, "auth succeeded"]
        if cmds[0] == 'pkulogin':
            logger.info ("handle request : PKU user login")
            url = "https://iaaa.pku.edu.cn/iaaaWS/TokenValidation?WSDL"
            remoteaddr = form.getvalue("ip")
            appid = "iwork"
            token = form.getvalue("token")
            key = "<KEY>"
            msg = remoteaddr + appid + token + key
            m = hashlib.md5()
            m.update(msg.encode("utf8"))
            msg = m.hexdigest()

            client = Client(url)
            result = dict(client.service.validate(remoteaddr, appid, token, msg))
            if (result['Status'] != 0):
                self.response(200, {'success':'false',  'result': result})
                return result
            result = G_usermgr.auth_iaaa(result['Info'])
            self.response(200, result)
            return result

        token = form.getvalue("token")
        if token == None:
            self.response(401, {'success':'false', 'message':'user or key is null'})
            return [False, "auth failed"]
        cur_user = G_usermgr.auth_token(token)
        if cur_user == None:
            self.response(401, {'success':'false', 'message':'token failed or expired', 'Unauthorized': 'True'})
            return [False, "auth failed"]



        user = cur_user.username
        # parse the url and get to do actions
        # /cluster/list
        # /cluster/create  &  clustername
        # /cluster/start    &  clustername
        # /cluster/stop    &  clustername
        # /cluster/delete    &  clustername
        # /cluster/info    &  clustername


        if cmds[0] == 'cluster':
            clustername = form.getvalue('clustername')
            # check for 'clustername' : all actions except 'list' need 'clustername'
            if (cmds[1] != 'list') and clustername == None:
                self.response(401, {'success':'false', 'message':'clustername is null'})
                return [False, "clustername is null"]
            if cmds[1] == 'create':
                image = {}
                image['name'] = form.getvalue("imagename")
                image['type'] = form.getvalue("imagetype")
                image['owner'] = form.getvalue("imageowner")
                onenode = form.getvalue('onenode')
                multinodes = form.getvalue('multinodes')
                #logger.info ('onende : %s, multinodes : %s' % (onenode, multinodes))
                logger.info ("handle request : create cluster %s with image %s " % (clustername, image['name']))
                [status, result] = G_vclustermgr.create_cluster(clustername, user, image, onenode, multinodes)
                if status:
                    self.response(200, {'success':'true', 'action':'create cluster', 'message':result})
                else:
                    self.response(200, {'success':'false', 'action':'create cluster', 'message':result})
            elif cmds[1] == 'scaleout':
                logger.info("handle request : scale out %s" % clustername)
                image = {}
                image['name'] = form.getvalue("imagename")
                image['type'] = form.getvalue("imagetype")
                image['owner'] = form.getvalue("imageowner")
                logger.debug("imagename:" + image['name'])
                logger.debug("imagetype:" + image['type'])
                logger.debug("imageowner:" + image['owner'])
                [status, result] = G_vclustermgr.scale_out_cluster(clustername, user, image)
                if status:
                    self.response(200, {'success':'true', 'action':'scale out', 'message':result})
                else:
                    self.response(200, {'success':'false', 'action':'scale out', 'message':result})
            elif cmds[1] == 'scalein':
                logger.info("handle request : scale in %s" % clustername)
                containername = form.getvalue("containername")
                [status, result] = G_vclustermgr.scale_in_cluster(clustername, user, containername)
                if status:
                    self.response(200, {'success':'true', 'action':'scale in', 'message':result})
                else:
                    self.response(200, {'success':'false', 'action':'scale in', 'message':result})
            elif cmds[1] == 'start':
                logger.info ("handle request : start cluster %s" % clustername)
                [status, result] = G_vclustermgr.start_cluster(clustername, user)
                if status:
                    # add proxy in configurable-http-proxy
                    [infostatus, clusterinfo] = G_vclustermgr.get_clusterinfo(clustername, user)
                    if clusterinfo['size'] > 0:
                        target = 'http://' + clusterinfo['containers'][0]['ip'].split('/')[0]+":10000"
                        proxytool.set_route('go/'+user+'/'+clustername, target)
                    self.response(200, {'success':'true', 'action':'start cluster', 'message':result})
                else:
                    self.response(200, {'success':'false', 'action':'start cluster', 'message':result})
            elif cmds[1] == 'stop':
                logger.info ("handle request : stop cluster %s" % clustername)
                [status, result] = G_vclustermgr.stop_cluster(clustername, user)
                if status:
                    # delete proxy in configurable-http-proxy
                    [infostatus, clusterinfo] = G_vclustermgr.get_clusterinfo(clustername, user)
                    # target = 'http://' + clusterinfo['containers'][0]['ip'].split('/')[0]+":10000"
                    proxytool.delete_route('go/'+user+'/'+clustername)
                    self.response(200, {'success':'true', 'action':'stop cluster', 'message':result})
                else:
                    self.response(200, {'success':'false', 'action':'stop cluster', 'message':result})
            elif cmds[1] == 'delete':
                logger.info ("handle request : delete cluster %s" % clustername)
                [status, result] = G_vclustermgr.delete_cluster(clustername, user)
                if status:
                    self.response(200, {'success':'true', 'action':'delete cluster', 'message':result})
                else:
                    self.response(200, {'success':'false', 'action':'delete cluster', 'message':result})
            elif cmds[1] == 'info':
                logger.info ("handle request : info cluster %s" % clustername)
                [status, result] = G_vclustermgr.get_clusterinfo(clustername, user)
                if status:
                    self.response(200, {'success':'true', 'action':'info cluster', 'message':result})
                else:
                    self.response(200, {'success':'false', 'action':'info cluster', 'message':result})
            elif cmds[1] == 'list':
                logger.info ("handle request : list clusters for %s" % user)
                [status, clusterlist] = G_vclustermgr.list_clusters(user)
                if status:
                    self.response(200, {'success':'true', 'action':'list cluster', 'clusters':clusterlist})
                else:
                    self.response(400, {'success':'false', 'action':'list cluster', 'message':clusterlist})

            elif cmds[1] == 'flush':
                from_lxc = form.getvalue('from_lxc')
                G_vclustermgr.flush_cluster(user,clustername,from_lxc)
                self.response(200, {'success':'true', 'action':'flush'})

            elif cmds[1] == 'save':
                imagename = form.getvalue("image")
                description = form.getvalue("description")
                containername = form.getvalue("containername")
                isforce = form.getvalue("isforce")
                if isforce == "true":
                    isforce = True
                else:
                    isforce = False
                [status,message] = G_vclustermgr.create_image(user,clustername,containername,imagename,description,isforce)
                if status:
                    logger.info("image has been saved")
                    self.response(200, {'success':'true', 'action':'save'})
                else:
                    logger.debug(message)
                    self.response(400, {'success':'false', 'message':message})

            else:
                logger.warning ("request not supported ")
                self.response(400, {'success':'false', 'message':'not supported request'})

        elif cmds[0] == 'image':
            if cmds[1] == 'list':
                images = G_imagemgr.list_images(user)
                self.response(200, {'success':'true', 'images': images})
            elif cmds[1] == 'description':
                image = {}
                image['name'] = form.getvalue("imagename")
                image['type'] = form.getvalue("imagetype")
                image['owner'] = form.getvalue("imageowner")
                description = G_imagemgr.get_image_description(user,image)
                self.response(200, {'success':'true', 'message':description})
            elif cmds[1] == 'share':
                image = form.getvalue('image')
                G_imagemgr.shareImage(user,image)
                self.response(200, {'success':'true', 'action':'share'})
            elif cmds[1] == 'unshare':
                image = form.getvalue('image')
                G_imagemgr.unshareImage(user,image)
                self.response(200, {'success':'true', 'action':'unshare'})
            elif cmds[1] == 'delete':
                image = form.getvalue('image')
                G_imagemgr.removeImage(user,image)
                self.response(200, {'success':'true', 'action':'delete'})
            else:
                logger.warning("request not supported ")
                self.response(400, {'success':'false', 'message':'not supported request'})
        # Request for Monitor
        elif cmds[0] == 'monitor':
            logger.info("handle request: monitor")
            res = {}
            if cmds[1] == 'real':
                com_id = cmds[2]
                fetcher = monitor.Fetcher(etcdaddr,G_clustername,com_id)
                if cmds[3] == 'meminfo':
                    res['meminfo'] = fetcher.get_meminfo()
                elif cmds[3] == 'cpuinfo':
                    res['cpuinfo'] = fetcher.get_cpuinfo()
                elif cmds[3] == 'cpuconfig':
                    res['cpuconfig'] = fetcher.get_cpuconfig()
                elif cmds[3] == 'diskinfo':
                    res['diskinfo'] = fetcher.get_diskinfo()
                elif cmds[3] == 'osinfo':
                    res['osinfo'] = fetcher.get_osinfo()
                elif cmds[3] == 'containers':
                    res['containers'] = fetcher.get_containers()
                elif cmds[3] == 'status':
                    res['status'] = fetcher.get_status()
                elif cmds[3] == 'containerslist':
                    res['containerslist'] = fetcher.get_containerslist()
                elif cmds[3] == 'containersinfo':
                    res = []
                    conlist = fetcher.get_containerslist()
                    for container in conlist:
                        ans = {}
                        confetcher = monitor.Container_Fetcher(etcdaddr,G_clustername)
                        ans = confetcher.get_basic_info(container)
                        ans['cpu_use'] = confetcher.get_cpu_use(container)
                        ans['mem_use'] = confetcher.get_mem_use(container)
                        res.append(ans)
                else:
                    self.response(400, {'success':'false', 'message':'not supported request'})
                    return

                self.response(200, {'success':'true', 'monitor':res})
            elif cmds[1] == 'node':
                fetcher = monitor.Container_Fetcher(etcdaddr,G_clustername)
                if cmds[3] == 'cpu_use':
                    res['cpu_use'] = fetcher.get_cpu_use(cmds[2])
                elif cmds[3] == 'mem_use':
                    res['mem_use'] = fetcher.get_mem_use(cmds[2])
                elif cmds[3] == 'basic_info':
                    res['basic_info'] = fetcher.get_basic_info(cmds[2])
                self.response(200, {'success':'true', 'monitor':res})
            elif cmds[1] == 'user':
                if not user == 'root':
                    self.response(400, {'success':'false', 'message':'Root Required'})
                if cmds[3] == 'clustercnt':
                    flag = True
                    clutotal = 0
                    clurun = 0
                    contotal = 0
                    conrun = 0
                    [status, clusterlist] = G_vclustermgr.list_clusters(cmds[2])
                    if status:
                        for clustername in clusterlist:
                            clutotal += 1
                            [status2, result] = G_vclustermgr.get_clusterinfo(clustername, cmds[2])
                            if status2:
                                contotal += result['size']
                                if result['status'] == 'running':
                                    clurun += 1
                                    conrun += result['size']
                    else:
                         flag = False
                    if flag:
                         res = {}
                         res['clutotal'] = clutotal
                         res['clurun'] = clurun
                         res['contotal'] = contotal
                         res['conrun'] = conrun
                         self.response(200, {'success':'true', 'monitor':{'clustercnt':res}})
                    else:
                         self.response(200, {'success':'false','message':clusterlist})
                elif cmds[3] == 'cluster':
                    if cmds[4] == 'list':
                        [status, clusterlist] = G_vclustermgr.list_clusters(cmds[2])
                        if status:
                            self.response(200, {'success':'true', 'monitor':{'clusters':clusterlist}})
                        else:
                            self.response(400, {'success':'false', 'message':clusterlist})
                    elif cmds[4] == 'info':
                        clustername = form.getvalue('clustername')
                        logger.info ("handle request : info cluster %s" % clustername)
                        [status, result] = G_vclustermgr.get_clusterinfo(clustername, user)
                        if status:
                            self.response(200, {'success':'true', 'monitor':{'info':result}})
                        else:
                     	    self.response(200, {'success':'false','message':result})
                    else:
                        self.response(400, {'success':'false', 'message':'not supported request'})

            elif cmds[1] == 'listphynodes':
                res['allnodes'] = G_nodemgr.get_allnodes()
                self.response(200, {'success':'true', 'monitor':res})
        # Request for User
        elif cmds[0] == 'user':
            logger.info("handle request: user")
            if cmds[1] == 'modify':
                #user = G_usermgr.query(username = form.getvalue("username"), cur_user = cur_user).get('token',  None)
                result = G_usermgr.modify(newValue = form, cur_user = cur_user)
                self.response(200, result)
            if cmds[1] == 'groupModify':
                result = G_usermgr.groupModify(newValue = form, cur_user = cur_user)
                self.response(200, result)
            if cmds[1] == 'query':
                result = G_usermgr.query(ID = form.getvalue("ID"), cur_user = cur_user)
                if (result.get('success', None) == None or result.get('success', None) == "false"):
                    self.response(301,result)
                else:
                    result = G_usermgr.queryForDisplay(user = result['token'])
                    self.response(200,result)

            elif cmds[1] == 'add':
                user = G_usermgr.newuser(cur_user = cur_user)
                user.username = form.getvalue('username')
                user.password = form.getvalue('password')
                user.e_mail = form.getvalue('e_mail', '')
                user.status = "normal"
                result = G_usermgr.register(user = user, cur_user = cur_user)
                self.response(200, result)
            elif cmds[1] == 'groupadd':
                result = G_usermgr.groupadd(name = form.getvalue('name', None), cur_user = cur_user)
                self.response(200, result)
            elif cmds[1] == 'data':
                logger.info("handle request: user/data")
                result = G_usermgr.userList(cur_user = cur_user)
                self.response(200, result)
            elif cmds[1] == 'groupNameList':
                result = G_usermgr.groupListName(cur_user = cur_user)
                self.response(200, result)
            elif cmds[1] == 'groupList':
                result = G_usermgr.groupList(cur_user = cur_user)
                self.response(200, result)
            elif cmds[1] == 'groupQuery':
                result = G_usermgr.groupQuery(ID = form.getvalue("ID", '3'), cur_user = cur_user)
                if (result.get('success', None) == None or result.get('success', None) == "false"):
                    self.response(301,result)
                else:
                    self.response(200,result)
            elif cmds[1] == 'selfQuery':
                result = G_usermgr.selfQuery(cur_user = cur_user)
                self.response(200,result)
            elif cmds[1] == 'selfModify':
                result = G_usermgr.selfModify(cur_user = cur_user, newValue = form)
                self.response(200,result)
        elif cmds[0] == 'register' :
            #activate
            logger.info("handle request: user/activate")
            newuser = G_usermgr.newuser()
            newuser.username = cur_user.username
            newuser.nickname = cur_user.truename
            newuser.status = 'applying'
            newuser.user_group = cur_user.user_group
            newuser.auth_method = cur_user.auth_method
            newuser.e_mail = form.getvalue('email','')
            newuser.student_number = form.getvalue('studentnumber', '')
            newuser.department = form.getvalue('department', '')
            newuser.truename = form.getvalue('truename', '')
            newuser.tel = form.getvalue('tel', '')
            result = G_usermgr.register(user = newuser)
            self.response(200,result)
        elif cmds[0] == 'service' :
            logger.info('handle request: service')
            if cmds[1] == 'list' :
                imagename = form.getvalue('imagename', 'base')
                username = form.getvalue('username', 'base')
                isshared = form.getvalue('isshared', 'base')
                result = G_servicemgr.list_service(imagename, username, isshared)
                self.response(200, result)
        else:
            logger.warning ("request not supported ")
            self.response(400, {'success':'false', 'message':'not supported request'})

class ThreadingHttpServer(ThreadingMixIn, http.server.HTTPServer):
    pass

if __name__ == '__main__':
    global G_nodemgr
    global G_vclustermgr
    global G_usermgr
    global etcdclient
    global G_networkmgr
    global G_clustername
    global G_servicemgr
    # move 'tools.loadenv' to the beginning of this file

    fs_path = env.getenv("FS_PREFIX")
    logger.info("using FS_PREFIX %s" % fs_path)

    etcdaddr = env.getenv("ETCD")
    logger.info("using ETCD %s" % etcdaddr)

    G_clustername = env.getenv("CLUSTER_NAME")
    logger.info("using CLUSTER_NAME %s" % G_clustername)

    # get network interface
    net_dev = env.getenv("NETWORK_DEVICE")
    logger.info("using NETWORK_DEVICE %s" % net_dev)

    ipaddr = network.getip(net_dev)
    if ipaddr==False:
        logger.error("network device is not correct")
        sys.exit(1)
    else:
        logger.info("using ipaddr %s" % ipaddr)

    # init etcdlib client
    try:
        etcdclient = etcdlib.Client(etcdaddr, prefix = G_clustername)
    except Exception:
        logger.error ("connect etcd failed, maybe etcd address not correct...")
        sys.exit(1)
    mode = 'recovery'
    if len(sys.argv) > 1 and sys.argv[1] == "new":
        mode = 'new'

    # do some initialization for mode: new/recovery
    if mode == 'new':
        # clean and initialize the etcd table
        if etcdclient.isdir(""):
            etcdclient.clean()
        else:
            etcdclient.createdir("")
        token = tools.gen_token()
        tokenfile = open(fs_path+"/global/token", 'w')
        tokenfile.write(token)
        tokenfile.write("\n")
        tokenfile.close()
        etcdclient.setkey("token", token)
        etcdclient.setkey("service/master", ipaddr)
        etcdclient.setkey("service/mode", mode)
        etcdclient.createdir("machines/allnodes")
        etcdclient.createdir("machines/runnodes")
        etcdclient.setkey("vcluster/nextid", "1")
        # clean all users vclusters files : FS_PREFIX/global/users/<username>/clusters/<clusterid>
        usersdir = fs_path+"/global/users/"
        for user in os.listdir(usersdir):
            shutil.rmtree(usersdir+user+"/clusters")
            shutil.rmtree(usersdir+user+"/hosts")
            os.mkdir(usersdir+user+"/clusters")
            os.mkdir(usersdir+user+"/hosts")
    else:
        # check whether cluster exists
        if not etcdclient.isdir("")[0]:
            logger.error ("cluster not exists, you should use mode:new ")
            sys.exit(1)
        # initialize the etcd table for recovery
        token = tools.gen_token()
        tokenfile = open(fs_path+"/global/token", 'w')
        tokenfile.write(token)
        tokenfile.write("\n")
        tokenfile.close()
        etcdclient.setkey("token", token)
        etcdclient.setkey("service/master", ipaddr)
        etcdclient.setkey("service/mode", mode)
        if etcdclient.isdir("_lock")[0]:
            etcdclient.deldir("_lock")
        if etcdclient.isdir("machines/runnodes")[0]:
            etcdclient.deldir("machines/runnodes")
        etcdclient.createdir("machines/runnodes")

    G_usermgr = userManager('root', 'unias1616')
    clusternet = env.getenv("CLUSTER_NET")
    logger.info("using CLUSTER_NET %s" % clusternet)

    G_networkmgr = network.NetworkMgr(clusternet, etcdclient, mode)
    G_networkmgr.printpools()

    # start NodeMgr and NodeMgr will wait for all nodes to start ...
    G_nodemgr = nodemgr.NodeMgr(G_networkmgr, etcdclient, addr = ipaddr)
    logger.info("nodemgr started")
    G_vclustermgr = vclustermgr.VclusterMgr(G_nodemgr, G_networkmgr, etcdclient, ipaddr, mode)
    logger.info("vclustermgr started")
    G_imagemgr = imagemgr.ImageMgr()
    logger.info("imagemgr started")
    Guest_control = guest_control.Guest(G_vclustermgr,G_nodemgr)
    G_servicemgr = servicemgr.ServiceMgr()
    logger.info("servicemgr started")
    logger.info("guest control started")
    threading.Thread(target=Guest_control.work, args=()).start()

    logger.info("startting to listen on: ")
    masterip = env.getenv('MASTER_IP')
    logger.info("using MASTER_IP %s", masterip)

    masterport = env.getenv('MASTER_PORT')
    logger.info("using MASTER_PORT %d", masterport)

#   server = http.server.HTTPServer((masterip, masterport), DockletHttpHandler)
    server = ThreadingHttpServer((masterip, masterport), DockletHttpHandler)
    logger.info("starting master server")
    server.serve_forever()

#!/usr/bin/python3

# load environment variables in the beginning
# because some modules need variables when import
# for example, userManager/model.py

# must first init loadenv
import tools, env
config = env.getenv("CONFIG")
tools.loadenv(config)

# second init logging
# must import logger after initlogging, ugly
from log import initlogging
initlogging("docklet-master")
from log import logger

import os
import http.server, cgi, json, sys, shutil
from socketserver import ThreadingMixIn
import nodemgr, vclustermgr, etcdlib, network, imagemgr, servicemgr
from userManager import userManager
import monitor
import proxytool
import guest_control, threading

import hashlib
from suds.client import Client
import requests

class DockletHttpHandler(http.server.BaseHTTPRequestHandler):
    def response(self, code, output):
        self.send_response(code)
        self.send_header("Content-type", "application/json")
        self.end_headers()
        # wfile/rfile are in byte/binary encoded. need to recode
        self.wfile.write(json.dumps(output).encode('ascii'))
        self.wfile.write("\n".encode('ascii'))
        # do not wfile.close()
        # because self.handle_one_request will call wfile.flush after calling do_*
        # and self.handle_one_request will close this wfile after timeout automatically
        # (see  /usr/lib/python3.4/http/server.py handle_one_request function)
        #self.wfile.close()

    # override log_request to not print default request log
    # we use the log info by ourselves in our style
    def log_request(code = '-', size = '-'):
        pass

    def do_PUT(self):
        self.response(400, {'success':'false', 'message':'Not supported methond'})

    def do_GET(self):
        self.response(400, {'success':'false', 'message':'Not supported methond'})

    def do_DELETE(self):
        self.response(400, {'success':'false', 'message':'Not supported methond'})

    # handler POST request
    def do_POST(self):
        global G_vclustermgr
        global G_usermgr
        #logger.info ("get request, header content:\n%s" % self.headers)
        #logger.info ("read request content:\n%s" % self.rfile.read(int(self.headers["Content-Length"])))
        logger.info ("get request, path: %s" % self.path)
        # for test
        if self.path == '/test':
            logger.info ("return welcome for test")
            self.response(200, {'success':'true', 'message':'welcome to docklet'})
            return [True, 'test ok']

        # check for not null content
        if 'Content-Length' not in self.headers:
            logger.info ("request content is null")
            self.response(401, {'success':'false', 'message':'request content is null'})
            return [False, 'content is null']

        # auth the user
        # cgi.FieldStorage need fp/headers/environ. (see /usr/lib/python3.4/cgi.py)
        form = cgi.FieldStorage(fp=self.rfile, headers=self.headers,environ={'REQUEST_METHOD':'POST'})
        cmds = self.path.strip('/').split('/')
        if cmds[0] == 'register' and form.getvalue('activate', None) == None:
            logger.info ("handle request : user register")
            username = form.getvalue('username', '')
            password = form.getvalue('password', '')
            email = form.getvalue('email', '')
            description = form.getvalue('description','')
            if (username == '' or password == '' or email == ''):
                self.response(500, {'success':'false'})
            newuser = G_usermgr.newuser()
            newuser.username = form.getvalue('username')
            newuser.password = form.getvalue('password')
            newuser.e_mail = form.getvalue('email')
            newuser.student_number = form.getvalue('studentnumber')
            newuser.department = form.getvalue('department')
            newuser.nickname = form.getvalue('truename')
            newuser.truename = form.getvalue('truename')
            newuser.description = form.getvalue('description')
            newuser.status = "init"
            newuser.auth_method = "local"
            result = G_usermgr.register(user = newuser)
            self.response(200, result)
            return [True, "register succeed"]
        if cmds[0] == 'login':
            logger.info ("handle request : user login")
            user = form.getvalue("user")
            key = form.getvalue("key")
            if user == None or key == None:
                self.response(401, {'success':'false', 'message':'user or key is null'})
                return [False, "auth failed"]
            auth_result = G_usermgr.auth(user, key)
            if  auth_result['success'] == 'false':
                self.response(401, {'success':'false', 'message':'auth failed'})
                return [False, "auth failed"]
            self.response(200, {'success':'true', 'action':'login', 'data': auth_result['data']})
            return [True, "auth succeeded"]
        if cmds[0] == 'pkulogin':
            logger.info ("handle request : PKU user login")
            url = "https://iaaa.pku.edu.cn/iaaaWS/TokenValidation?WSDL"
            remoteaddr = form.getvalue("ip")
            appid = "iwork"
            token = form.getvalue("token")
            key = "<KEY>"
            msg = remoteaddr + appid + token + key
            m = hashlib.md5()
            m.update(msg.encode("utf8"))
            msg = m.hexdigest()

            client = Client(url)
            result = dict(client.service.validate(remoteaddr, appid, token, msg))
            if (result['Status'] != 0):
                self.response(200, {'success':'false',  'result': result})
                return result
            result = G_usermgr.auth_iaaa(result['Info'])
            self.response(200, result)
            return result

        token = form.getvalue("token")
        if token == None:
            self.response(401, {'success':'false', 'message':'user or key is null'})
            return [False, "auth failed"]
        cur_user = G_usermgr.auth_token(token)
        if cur_user == None:
            self.response(401, {'success':'false', 'message':'token failed or expired', 'Unauthorized': 'True'})
            return [False, "auth failed"]



        user = cur_user.username
        # parse the url and get to do actions
        # /cluster/list
        # /cluster/create  &  clustername
        # /cluster/start    &  clustername
        # /cluster/stop    &  clustername
        # /cluster/delete    &  clustername
        # /cluster/info    &  clustername


        if cmds[0] == 'cluster':
            clustername = form.getvalue('clustername')
            # check for 'clustername' : all actions except 'list' need 'clustername'
            if (cmds[1] != 'list') and clustername == None:
                self.response(401, {'success':'false', 'message':'clustername is null'})
                return [False, "clustername is null"]
            if cmds[1] == 'create':
                image = {}
                image['name'] = form.getvalue("imagename")
                image['type'] = form.getvalue("imagetype")
                image['owner'] = form.getvalue("imageowner")
                onenode = form.getvalue('onenode')
                multinodes = form.getvalue('multinodes')
                #logger.info ('onende : %s, multinodes : %s' % (onenode, multinodes))
                logger.info ("handle request : create cluster %s with image %s " % (clustername, image['name']))
                [status, result] = G_vclustermgr.create_cluster(clustername, user, image, onenode, multinodes)
                if status:
                    self.response(200, {'success':'true', 'action':'create cluster', 'message':result})
                else:
                    self.response(200, {'success':'false', 'action':'create cluster', 'message':result})
            elif cmds[1] == 'scaleout':
                logger.info("handle request : scale out %s" % clustername)
                image = {}
                image['name'] = form.getvalue("imagename")
                image['type'] = form.getvalue("imagetype")
                image['owner'] = form.getvalue("imageowner")
                logger.debug("imagename:" + image['name'])
                logger.debug("imagetype:" + image['type'])
                logger.debug("imageowner:" + image['owner'])
                [status, result] = G_vclustermgr.scale_out_cluster(clustername, user, image)
                if status:
                    self.response(200, {'success':'true', 'action':'scale out', 'message':result})
                else:
                    self.response(200, {'success':'false', 'action':'scale out', 'message':result})
            elif cmds[1] == 'scalein':
                logger.info("handle request : scale in %s" % clustername)
                containername = form.getvalue("containername")
                [status, result] = G_vclustermgr.scale_in_cluster(clustername, user, containername)
                if status:
                    self.response(200, {'success':'true', 'action':'scale in', 'message':result})
                else:
                    self.response(200, {'success':'false', 'action':'scale in', 'message':result})
            elif cmds[1] == 'start':
                logger.info ("handle request : start cluster %s" % clustername)
                [status, result] = G_vclustermgr.start_cluster(clustername, user)
                if status:
                    # add proxy in configurable-http-proxy
                    [infostatus, clusterinfo] = G_vclustermgr.get_clusterinfo(clustername, user)
                    if clusterinfo['size'] > 0:
                        target = 'http://' + clusterinfo['containers'][0]['ip'].split('/')[0]+":10000"
                        proxytool.set_route('go/'+user+'/'+clustername, target)
                    self.response(200, {'success':'true', 'action':'start cluster', 'message':result})
                else:
                    self.response(200, {'success':'false', 'action':'start cluster', 'message':result})
            elif cmds[1] == 'stop':
                logger.info ("handle request : stop cluster %s" % clustername)
                [status, result] = G_vclustermgr.stop_cluster(clustername, user)
                if status:
                    # delete proxy in configurable-http-proxy
                    [infostatus, clusterinfo] = G_vclustermgr.get_clusterinfo(clustername, user)
                    # target = 'http://' + clusterinfo['containers'][0]['ip'].split('/')[0]+":10000"
                    proxytool.delete_route('go/'+user+'/'+clustername)
                    self.response(200, {'success':'true', 'action':'stop cluster', 'message':result})
                else:
                    self.response(200, {'success':'false', 'action':'stop cluster', 'message':result})
            elif cmds[1] == 'delete':
                logger.info ("handle request : delete cluster %s" % clustername)
                [status, result] = G_vclustermgr.delete_cluster(clustername, user)
                if status:
                    self.response(200, {'success':'true', 'action':'delete cluster', 'message':result})
                else:
                    self.response(200, {'success':'false', 'action':'delete cluster', 'message':result})
            elif cmds[1] == 'info':
                logger.info ("handle request : info cluster %s" % clustername)
                [status, result] = G_vclustermgr.get_clusterinfo(clustername, user)
                if status:
                    self.response(200, {'success':'true', 'action':'info cluster', 'message':result})
                else:
                    self.response(200, {'success':'false', 'action':'info cluster', 'message':result})
            elif cmds[1] == 'list':
                logger.info ("handle request : list clusters for %s" % user)
                [status, clusterlist] = G_vclustermgr.list_clusters(user)
                if status:
                    self.response(200, {'success':'true', 'action':'list cluster', 'clusters':clusterlist})
                else:
                    self.response(400, {'success':'false', 'action':'list cluster', 'message':clusterlist})

            elif cmds[1] == 'flush':
                from_lxc = form.getvalue('from_lxc')
                G_vclustermgr.flush_cluster(user,clustername,from_lxc)
                self.response(200, {'success':'true', 'action':'flush'})

            elif cmds[1] == 'save':
                imagename = form.getvalue("image")
                description = form.getvalue("description")
                containername = form.getvalue("containername")
                isforce = form.getvalue("isforce")
                if isforce == "true":
                    isforce = True
                else:
                    isforce = False
                [status,message] = G_vclustermgr.create_image(user,clustername,containername,imagename,description,isforce)
                if status:
                    logger.info("image has been saved")
                    self.response(200, {'success':'true', 'action':'save'})
                else:
                    logger.debug(message)
                    self.response(400, {'success':'false', 'message':message})

            else:
                logger.warning ("request not supported ")
                self.response(400, {'success':'false', 'message':'not supported request'})

        elif cmds[0] == 'image':
            if cmds[1] == 'list':
                images = G_imagemgr.list_images(user)
                self.response(200, {'success':'true', 'images': images})
            elif cmds[1] == 'description':
                image = {}
                image['name'] = form.getvalue("imagename")
                image['type'] = form.getvalue("imagetype")
                image['owner'] = form.getvalue("imageowner")
                description = G_imagemgr.get_image_description(user,image)
                self.response(200, {'success':'true', 'message':description})
            elif cmds[1] == 'share':
                image = form.getvalue('image')
                G_imagemgr.shareImage(user,image)
                self.response(200, {'success':'true', 'action':'share'})
            elif cmds[1] == 'unshare':
                image = form.getvalue('image')
                G_imagemgr.unshareImage(user,image)
                self.response(200, {'success':'true', 'action':'unshare'})
            elif cmds[1] == 'delete':
                image = form.getvalue('image')
                G_imagemgr.removeImage(user,image)
                self.response(200, {'success':'true', 'action':'delete'})
            else:
                logger.warning("request not supported ")
                self.response(400, {'success':'false', 'message':'not supported request'})
        # Request for Monitor
        elif cmds[0] == 'monitor':
            logger.info("handle request: monitor")
            res = {}
            if cmds[1] == 'real':
                com_id = cmds[2]
                fetcher = monitor.Fetcher(etcdaddr,G_clustername,com_id)
                if cmds[3] == 'meminfo':
                    res['meminfo'] = fetcher.get_meminfo()
                elif cmds[3] == 'cpuinfo':
                    res['cpuinfo'] = fetcher.get_cpuinfo()
                elif cmds[3] == 'cpuconfig':
                    res['cpuconfig'] = fetcher.get_cpuconfig()
                elif cmds[3] == 'diskinfo':
                    res['diskinfo'] = fetcher.get_diskinfo()
                elif cmds[3] == 'osinfo':
                    res['osinfo'] = fetcher.get_osinfo()
                elif cmds[3] == 'containers':
                    res['containers'] = fetcher.get_containers()
                elif cmds[3] == 'status':
                    res['status'] = fetcher.get_status()
                elif cmds[3] == 'containerslist':
                    res['containerslist'] = fetcher.get_containerslist()
                elif cmds[3] == 'containersinfo':
                    res = []
                    conlist = fetcher.get_containerslist()
                    for container in conlist:
                        ans = {}
                        confetcher = monitor.Container_Fetcher(etcdaddr,G_clustername)
                        ans = confetcher.get_basic_info(container)
                        ans['cpu_use'] = confetcher.get_cpu_use(container)
                        ans['mem_use'] = confetcher.get_mem_use(container)
                        res.append(ans)
                else:
                    self.response(400, {'success':'false', 'message':'not supported request'})
                    return

                self.response(200, {'success':'true', 'monitor':res})
            elif cmds[1] == 'node':
                fetcher = monitor.Container_Fetcher(etcdaddr,G_clustername)
                if cmds[3] == 'cpu_use':
                    res['cpu_use'] = fetcher.get_cpu_use(cmds[2])
                elif cmds[3] == 'mem_use':
                    res['mem_use'] = fetcher.get_mem_use(cmds[2])
                elif cmds[3] == 'basic_info':
                    res['basic_info'] = fetcher.get_basic_info(cmds[2])
                self.response(200, {'success':'true', 'monitor':res})
            elif cmds[1] == 'user':
                if not user == 'root':
                    self.response(400, {'success':'false', 'message':'Root Required'})
                if cmds[3] == 'clustercnt':
                    flag = True
                    clutotal = 0
                    clurun = 0
                    contotal = 0
                    conrun = 0
                    [status, clusterlist] = G_vclustermgr.list_clusters(cmds[2])
                    if status:
                        for clustername in clusterlist:
                            clutotal += 1
                            [status2, result] = G_vclustermgr.get_clusterinfo(clustername, cmds[2])
                            if status2:
                                contotal += result['size']
                                if result['status'] == 'running':
                                    clurun += 1
                                    conrun += result['size']
                    else:
                         flag = False
                    if flag:
                         res = {}
                         res['clutotal'] = clutotal
                         res['clurun'] = clurun
                         res['contotal'] = contotal
                         res['conrun'] = conrun
                         self.response(200, {'success':'true', 'monitor':{'clustercnt':res}})
                    else:
                         self.response(200, {'success':'false','message':clusterlist})
                elif cmds[3] == 'cluster':
                    if cmds[4] == 'list':
                        [status, clusterlist] = G_vclustermgr.list_clusters(cmds[2])
                        if status:
                            self.response(200, {'success':'true', 'monitor':{'clusters':clusterlist}})
                        else:
                            self.response(400, {'success':'false', 'message':clusterlist})
                    elif cmds[4] == 'info':
                        clustername = form.getvalue('clustername')
                        logger.info ("handle request : info cluster %s" % clustername)
                        [status, result] = G_vclustermgr.get_clusterinfo(clustername, user)
                        if status:
                            self.response(200, {'success':'true', 'monitor':{'info':result}})
                        else:
                     	    self.response(200, {'success':'false','message':result})
                    else:
                        self.response(400, {'success':'false', 'message':'not supported request'})

            elif cmds[1] == 'listphynodes':
                res['allnodes'] = G_nodemgr.get_allnodes()
                self.response(200, {'success':'true', 'monitor':res})
        # Request for User
        elif cmds[0] == 'user':
            logger.info("handle request: user")
            if cmds[1] == 'modify':
                #user = G_usermgr.query(username = form.getvalue("username"), cur_user = cur_user).get('token',  None)
                result = G_usermgr.modify(newValue = form, cur_user = cur_user)
                self.response(200, result)
            if cmds[1] == 'groupModify':
                result = G_usermgr.groupModify(newValue = form, cur_user = cur_user)
                self.response(200, result)
            if cmds[1] == 'query':
                result = G_usermgr.query(ID = form.getvalue("ID"), cur_user = cur_user)
                if (result.get('success', None) == None or result.get('success', None) == "false"):
                    self.response(301,result)
                else:
                    result = G_usermgr.queryForDisplay(user = result['token'])
                    self.response(200,result)

            elif cmds[1] == 'add':
                user = G_usermgr.newuser(cur_user = cur_user)
                user.username = form.getvalue('username')
                user.password = form.getvalue('password')
                user.e_mail = form.getvalue('e_mail', '')
                user.status = "normal"
                result = G_usermgr.register(user = user, cur_user = cur_user)
                self.response(200, result)
            elif cmds[1] == 'groupadd':
                result = G_usermgr.groupadd(name = form.getvalue('name', None), cur_user = cur_user)
                self.response(200, result)
            elif cmds[1] == 'data':
                logger.info("handle request: user/data")
                result = G_usermgr.userList(cur_user = cur_user)
                self.response(200, result)
            elif cmds[1] == 'groupNameList':
                result = G_usermgr.groupListName(cur_user = cur_user)
                self.response(200, result)
            elif cmds[1] == 'groupList':
                result = G_usermgr.groupList(cur_user = cur_user)
                self.response(200, result)
            elif cmds[1] == 'groupQuery':
                result = G_usermgr.groupQuery(ID = form.getvalue("ID", '3'), cur_user = cur_user)
                if (result.get('success', None) == None or result.get('success', None) == "false"):
                    self.response(301,result)
                else:
                    self.response(200,result)
            elif cmds[1] == 'selfQuery':
                result = G_usermgr.selfQuery(cur_user = cur_user)
                self.response(200,result)
            elif cmds[1] == 'selfModify':
                result = G_usermgr.selfModify(cur_user = cur_user, newValue = form)
                self.response(200,result)
        elif cmds[0] == 'register' :
            #activate
            logger.info("handle request: user/activate")
            newuser = G_usermgr.newuser()
            newuser.username = cur_user.username
            newuser.nickname = cur_user.truename
            newuser.status = 'applying'
            newuser.user_group = cur_user.user_group
            newuser.auth_method = cur_user.auth_method
            newuser.e_mail = form.getvalue('email','')
            newuser.student_number = form.getvalue('studentnumber', '')
            newuser.department = form.getvalue('department', '')
            newuser.truename = form.getvalue('truename', '')
            newuser.tel = form.getvalue('tel', '')
            result = G_usermgr.register(user = newuser)
            self.response(200,result)
        elif cmds[0] == 'service' :
            logger.info('handle request: service')
            if cmds[1] == 'list' :
                imagename = form.getvalue('imagename', 'base')
                username = form.getvalue('username', 'base')
                isshared = form.getvalue('isshared', 'base')
                result = G_servicemgr.list_service(imagename, username, isshared)
                self.response(200, result)
        else:
            logger.warning ("request not supported ")
            self.response(400, {'success':'false', 'message':'not supported request'})

class ThreadingHttpServer(ThreadingMixIn, http.server.HTTPServer):
    pass

if __name__ == '__main__':
    global G_nodemgr
    global G_vclustermgr
    global G_usermgr
    global etcdclient
    global G_networkmgr
    global G_clustername
    global G_servicemgr
    # move 'tools.loadenv' to the beginning of this file

    fs_path = env.getenv("FS_PREFIX")
    logger.info("using FS_PREFIX %s" % fs_path)

    etcdaddr = env.getenv("ETCD")
    logger.info("using ETCD %s" % etcdaddr)

    G_clustername = env.getenv("CLUSTER_NAME")
    logger.info("using CLUSTER_NAME %s" % G_clustername)

    # get network interface
    net_dev = env.getenv("NETWORK_DEVICE")
    logger.info("using NETWORK_DEVICE %s" % net_dev)

    ipaddr = network.getip(net_dev)
    if ipaddr==False:
        logger.error("network device is not correct")
        sys.exit(1)
    else:
        logger.info("using ipaddr %s" % ipaddr)

    # init etcdlib client
    try:
        etcdclient = etcdlib.Client(etcdaddr, prefix = G_clustername)
    except Exception:
        logger.error ("connect etcd failed, maybe etcd address not correct...")
        sys.exit(1)
    mode = 'recovery'
    if len(sys.argv) > 1 and sys.argv[1] == "new":
        mode = 'new'

    # do some initialization for mode: new/recovery
    if mode == 'new':
        # clean and initialize the etcd table
        if etcdclient.isdir(""):
            etcdclient.clean()
        else:
            etcdclient.createdir("")
        token = tools.gen_token()
        tokenfile = open(fs_path+"/global/token", 'w')
        tokenfile.write(token)
        tokenfile.write("\n")
        tokenfile.close()
        etcdclient.setkey("token", token)
        etcdclient.setkey("service/master", ipaddr)
        etcdclient.setkey("service/mode", mode)
        etcdclient.createdir("machines/allnodes")
        etcdclient.createdir("machines/runnodes")
        etcdclient.setkey("vcluster/nextid", "1")
        # clean all users vclusters files : FS_PREFIX/global/users/<username>/clusters/<clusterid>
        usersdir = fs_path+"/global/users/"
        for user in os.listdir(usersdir):
            shutil.rmtree(usersdir+user+"/clusters")
            shutil.rmtree(usersdir+user+"/hosts")
            os.mkdir(usersdir+user+"/clusters")
            os.mkdir(usersdir+user+"/hosts")
    else:
        # check whether cluster exists
        if not etcdclient.isdir("")[0]:
            logger.error ("cluster not exists, you should use mode:new ")
            sys.exit(1)
        # initialize the etcd table for recovery
        token = tools.gen_token()
        tokenfile = open(fs_path+"/global/token", 'w')
        tokenfile.write(token)
        tokenfile.write("\n")
        tokenfile.close()
        etcdclient.setkey("token", token)
        etcdclient.setkey("service/master", ipaddr)
        etcdclient.setkey("service/mode", mode)
        if etcdclient.isdir("_lock")[0]:
            etcdclient.deldir("_lock")
        if etcdclient.isdir("machines/runnodes")[0]:
            etcdclient.deldir("machines/runnodes")
        etcdclient.createdir("machines/runnodes")

    G_usermgr = userManager('root', 'unias1616')
    clusternet = env.getenv("CLUSTER_NET")
    logger.info("using CLUSTER_NET %s" % clusternet)

    G_networkmgr = network.NetworkMgr(clusternet, etcdclient, mode)
    G_networkmgr.printpools()

    # start NodeMgr and NodeMgr will wait for all nodes to start ...
    G_nodemgr = nodemgr.NodeMgr(G_networkmgr, etcdclient, addr = ipaddr)
    logger.info("nodemgr started")
    G_vclustermgr = vclustermgr.VclusterMgr(G_nodemgr, G_networkmgr, etcdclient, ipaddr, mode)
    logger.info("vclustermgr started")
    G_imagemgr = imagemgr.ImageMgr()
    logger.info("imagemgr started")
    Guest_control = guest_control.Guest(G_vclustermgr,G_nodemgr)
    G_servicemgr = servicemgr.ServiceMgr()
    logger.info("servicemgr started")
    logger.info("guest control started")
    threading.Thread(target=Guest_control.work, args=()).start()

    logger.info("startting to listen on: ")
    masterip = env.getenv('MASTER_IP')
    logger.info("using MASTER_IP %s", masterip)

    masterport = env.getenv('MASTER_PORT')
    logger.info("using MASTER_PORT %d", masterport)

#   server = http.server.HTTPServer((masterip, masterport), DockletHttpHandler)
    server = ThreadingHttpServer((masterip, masterport), DockletHttpHandler)
    logger.info("starting master server")
    server.serve_forever()
#!/usr/bin/python3 # load environment variables in the beginning # because some modules need variables when import # for example, userManager/model.py # must first init loadenv # second init logging # must import logger after initlogging, ugly # wfile/rfile are in byte/binary encoded. need to recode # do not wfile.close() # because self.handle_one_request will call wfile.flush after calling do_* # and self.handle_one_request will close this wfile after timeout automatically # (see  /usr/lib/python3.4/http/server.py handle_one_request function) #self.wfile.close() # override log_request to not print default request log # we use the log info by ourselves in our style # handler POST request #logger.info ("get request, header content:\n%s" % self.headers) #logger.info ("read request content:\n%s" % self.rfile.read(int(self.headers["Content-Length"]))) # for test # check for not null content # auth the user # cgi.FieldStorage need fp/headers/environ. (see /usr/lib/python3.4/cgi.py) # parse the url and get to do actions # /cluster/list # /cluster/create  &  clustername # /cluster/start    &  clustername # /cluster/stop    &  clustername # /cluster/delete    &  clustername # /cluster/info    &  clustername # check for 'clustername' : all actions except 'list' need 'clustername' #logger.info ('onende : %s, multinodes : %s' % (onenode, multinodes)) # add proxy in configurable-http-proxy # delete proxy in configurable-http-proxy # target = 'http://' + clusterinfo['containers'][0]['ip'].split('/')[0]+":10000" # Request for Monitor # Request for User #user = G_usermgr.query(username = form.getvalue("username"), cur_user = cur_user).get('token',  None) #activate # move 'tools.loadenv' to the beginning of this file # get network interface # init etcdlib client # do some initialization for mode: new/recovery # clean and initialize the etcd table # clean all users vclusters files : FS_PREFIX/global/users/<username>/clusters/<clusterid> # check whether cluster exists # initialize the etcd table for recovery # start NodeMgr and NodeMgr will wait for all nodes to start ... #   server = http.server.HTTPServer((masterip, masterport), DockletHttpHandler)