def __getDeviceSize(self, device_id):
     '''
     get device size from /proc/partitions
     @param device_id:
     @type device_id:
     @return: device size
     @rtype: long
     @raise ERR_INPUT_IDNOTEXIST: device not exist
     '''
     f = open("/proc/partitions", "r")
     lines = f.readlines()
     devline = [line for line in lines if line.endswith("%s\n" % device_id)]
     if not len(devline) == 1:
         raise VFOSERR("device [%s] not exist" % device_id,
                       VFOSERR.ERR_INPUT_IDNOTEXIST)
     dev_info = devline[0].split()
     dev_size = long(dev_info[2]) * 1024
     f.close()
     return dev_size
    def __syncTaskProgress(self, task_uuid):
        '''
        @rtype: schema_progress_info
        @return: schema_progress_info = {
            "status":TASK_STATUS,
            "result":RESULT_NONE,
            "progress":20,
            "message":"time elapse: 101 second",
            "debugmessage":""
        }
        '''
        try:
            if not self.task_list.has_key(task_uuid):
                raise VFOSERR("Task id not exist.", VFOSERR.ERR_IDNOTEXIST)

            progress = self.task_list[task_uuid]["task_progress"]

            taskinfo_path = os.path.join(self.conf["historytaskpath"],
                                         task_uuid)
            progressfile = os.path.join(taskinfo_path, "progress")
            resultfile = os.path.join(taskinfo_path, "result")
            messagefile = os.path.join(taskinfo_path, "message")
            statusfile = os.path.join(taskinfo_path, "status")
            debugfile = os.path.join(taskinfo_path, "logfile")
            #self.syslogger.debug(progressfile)

            progress.update({
                "result": getFileValue(resultfile),
                "status": getFileValue(statusfile),
                "message": getFileValue(messagefile),
                "debug_message": getFileValue(debugfile),
                "progress": 0
            })

            #self.syslogger.debug(" task info is %s " % str(progress))
            # adapt
            if not progress["status"]:
                progress["status"] = STATUS_NOTSTART
                progress["result"] = RESULT_NONE
            elif progress["status"] == STATUS_END:
                progress["progress"] = 100


#                progress['message'] = "task ended"
            elif progress["status"] == STATUS_BUSY:
                if os.path.exists(progressfile):
                    fp = os.popen("tail -1 " + progressfile)
                    fcontent = fp.read()
                    if fcontent:
                        arr = fcontent.split()
                        progress['message'] += ":" + fcontent
                        if "%" in arr[0]:
                            progress['progress'] = int(float(arr[0][0:-1]))
                        elif arr[0] == "100":
                            progress['progress'] = 100
                    fp.close()
                else:
                    progress['progress'] = 0
            else:
                progress['result'] = RESULT_UNKNOW
                progress['message'] = "unknow status!"

            if (0 == (progress['progress'] % 10)):
                self.syslogger.debug("Task progress:" +
                                     str(progress['progress']))

            return progress
        except Exception, e:
            self.syslogger.debug(str(e))
    def createImage(self, task_option, **kwargs):
        '''
        upload the disk to ftp server, as the task should take a long time, 
        so the task would run in background and return a task uuid.
        @param task_option:{
            "ftp_info":{
                "host":"",
                "username":"",
                "password":""
            },
            "dev_id":"hda",
            "task_uuid":"",
            "img_type":"",
            "img_name":"",
            "meta":""
        }
        '''
        if self.__checkCurTask():
            raise VFOSERR("have task running", VFOSERR.ERR_BUSY)

        if not "task_uuid" in task_option or not task_option["task_uuid"]:
            task_uuid = str(uuid4())
        else:
            task_uuid = task_option["task_uuid"]

        if self.task_list.has_key(task_uuid):
            raise VFOSERR("task id exist", VFOSERR.ERR_INPUT_IDEXIST)

        if not self.__checkDevice(task_option["dev_id"]):
            raise VFOSERR("device [%s] not exist" % task_option["dev_id"],
                          VFOSERR.ERR_INPUT_IDNOTEXIST)

        self.task_list[task_uuid] = copy.deepcopy(
            self.schema["schema_task_info"])
        self.task_list[task_uuid].update({
            "task_uuid":
            task_uuid,
            "task_key":
            str(uuid4()),
            "task_type":
            "Create_Image",
            "status":
            STATUS_NOTSTART,
            "result":
            RESULT_NONE,
            "task_option":
            task_option,
            "task_progress":
            copy.deepcopy(self.schema["schema_progress_info"])
        })
        self.current_task_uuid = task_uuid

        templatebased = True if task_option['templatebased'] == '' else False
        #'YES' if task_option['meta']['type']['is_basic']=='1' else 'NO'
        task_option["tpl_name"] = task_uuid
        #task_option['templatebased']="base"
        #task_option['templatebased']=templatebased
        task_option["img_name"] = "partition2.img"
        task_option["md5log"] = "YES"

        #1. create a thread to finished the job
        if templatebased:
            self.curtaskthread = threading.Thread(
                target=self.__createImageThread,
                args=(task_uuid, task_option),
                kwargs=kwargs)
        else:
            self.curtaskthread = threading.Thread(
                target=self.__createImagePatchThread,
                args=(task_uuid, task_option),
                kwargs=kwargs)
        self.curtaskthread.setDaemon(True)
        self.curtaskthread.start()

        ret = {'result': 0, 'return': task_uuid, 'message': "starting!"}
        return ret["return"]
    def installImage(self, task_option, **kwargs):
        '''
        download and install the disk from the web server[ftp,http,https], as the task should take a long time, 
        so the task would run in background and return a task uuid.
        @param task_option:  
                task_option:{
                    "img_info":{
                        "img_url":"",
                        "img_md5":"",
                        "img_size":"",
                        "img_type":""
                    },
                    "dev_id":"hda",
                    "task_uuid":""
                }
        @type task_option: schema_install_option 
        @return: task_uuid
        @rtype: schema_uuid
        @raise ERR_CON_STATUS_BUSY: have task running
        @raise ERR_INPUT_IDEXIST: task id exist
        @raise ERR_INPUT_IDNOTEXIST: device not exist
        '''

        # check input
        if self.__checkCurTask():
            raise VFOSERR("have task running", VFOSERR.ERR_CON_STATUS_BUSY)

        if not "task_uuid" in task_option or not task_option["task_uuid"]:
            task_uuid = str(uuid4())
        else:
            task_uuid = task_option["task_uuid"]

        if self.task_list.has_key(task_uuid):
            raise VFOSERR("Task id exist", VFOSERR.ERR_INPUT_IDEXIST)

#Default dev_id is sda2
#task_option["dev_id"]=CloudRainbowPub.getdisktype()+"2"
        if task_option["dev_id"] == "":
            task_option["dev_id"] = CloudRainbowPub.getdisktype() + "2"

        print '=========', task_option["dev_id"]

        if not self.__checkDevice(task_option["dev_id"]):
            raise VFOSERR("Device [%s] not exist" % task_option["dev_id"],
                          VFOSERR.ERR_INPUT_IDNOTEXIST)

        #dev_size = self.__getDeviceSize(task_option["dev_id"])
        dev_size = self.__getDeviceSize(task_option["dev_id"])
        if long(task_option["img_info"]["img_size"]) > dev_size:
            raise VFOSERR("Device size not too small", VFOSERR.ERR_INPUT)

        # register new task
        self.task_list[task_uuid] = copy.deepcopy(
            self.schema["schema_task_info"])
        self.task_list[task_uuid].update({
            "task_uuid":
            task_uuid,
            "task_key":
            str(uuid4()),
            "task_type":
            "Install_Image",
            "status":
            STATUS_NOTSTART,
            "result":
            RESULT_NONE,
            "task_option":
            task_option,
            "task_progress":
            copy.deepcopy(self.schema["schema_progress_info"])
        })
        self.current_task_uuid = task_uuid

        #        if kwargs.has_key("callback"):
        #            callback = kwargs["callback"]
        #        else:
        #            callback = None
        # create a thread to finished the job
        self.curtaskthread = threading.Thread(target=self.__installImageThread,
                                              args=(task_uuid, task_option),
                                              kwargs=kwargs)
        self.curtaskthread.setDaemon(True)
        self.curtaskthread.start()

        ret = {'result': 0, 'message': "starting!", "return": task_uuid}
        return ret["return"]