Example #1
0
    def __enter__(self):
        if self.exists_lock < self.target_lock:
            active_lv(self.abs_path, self.shared)
        if linux.qcow2_get_backing_file(self.abs_path) != "":
            self.backing = RecursiveOperateLv(linux.qcow2_get_backing_file(self.abs_path), True, False)

        if self.backing is not None:
            self.backing.__enter__()
Example #2
0
    def __enter__(self):
        if self.exists_lock < self.target_lock:
            active_lv(self.abs_path, self.shared)
        if linux.qcow2_get_backing_file(self.abs_path) != "":
            self.backing = RecursiveOperateLv(
                linux.qcow2_get_backing_file(self.abs_path), True, self.skip_deactivate_tags, False)

        if self.backing is not None:
            self.backing.__enter__()
Example #3
0
    def rebase_volume_backing_file(self, req):
        cmd = jsonobject.loads(req[http.REQUEST_BODY])
        rsp = NfsRebaseVolumeBackingFileRsp()

        if not cmd.dstImageCacheTemplateFolderPath:
            qcow2s = shell.call("find %s -type f -regex '.*\.qcow2$'" % cmd.dstVolumeFolderPath)
        else:
            qcow2s = shell.call("find %s %s -type f -regex '.*\.qcow2$'" % (cmd.dstVolumeFolderPath, cmd.dstImageCacheTemplateFolderPath))

        for qcow2 in qcow2s.split():
            fmt = shell.call("qemu-img info %s | grep '^file format' | awk -F ': ' '{ print $2 }'" % qcow2)
            if fmt.strip() != "qcow2":
                continue

            backing_file = linux.qcow2_get_backing_file(qcow2)
            if backing_file == "":
                continue

            # actions like `create snapshot -> recover snapshot -> delete snapshot` may produce garbage qcow2, whose backing file doesn't exist
            new_backing_file = backing_file.replace(cmd.srcPsMountPath, cmd.dstPsMountPath)
            if not os.path.exists(new_backing_file):
                logger.debug("the backing file[%s] of volume[%s] doesn't exist, skip rebasing" % (new_backing_file, qcow2))
                continue

            linux.qcow2_rebase_no_check(new_backing_file, qcow2)
        return jsonobject.dumps(rsp)
Example #4
0
    def rebase_volume_backing_file(self, req):
        cmd = jsonobject.loads(req[http.REQUEST_BODY])
        rsp = NfsRebaseVolumeBackingFileRsp()

        if not cmd.dstImageCacheTemplateFolderPath:
            qcow2s = shell.call("find %s -type f -regex '.*\.qcow2$'" %
                                cmd.dstVolumeFolderPath)
        else:
            qcow2s = shell.call(
                "find %s %s -type f -regex '.*\.qcow2$'" %
                (cmd.dstVolumeFolderPath, cmd.dstImageCacheTemplateFolderPath))

        for qcow2 in qcow2s.split():
            fmt = shell.call(
                "qemu-img info %s | grep '^file format' | awk -F ': ' '{ print $2 }'"
                % qcow2)
            if fmt.strip() != "qcow2":
                continue
            backing_file = linux.qcow2_get_backing_file(qcow2)
            if backing_file == "":
                continue
            new_backing_file = backing_file.replace(cmd.srcPsMountPath,
                                                    cmd.dstPsMountPath)
            linux.qcow2_rebase_no_check(new_backing_file, qcow2)
        return jsonobject.dumps(rsp)
    def migrate_volumes(self, req):
        cmd = jsonobject.loads(req[http.REQUEST_BODY])
        rsp = AgentRsp()

        for struct in cmd.migrateVolumeStructs:
            target_abs_path = translate_absolute_path_from_install_path(struct.targetInstallPath)
            current_abs_path = translate_absolute_path_from_install_path(struct.currentInstallPath)
            with lvm.OperateLv(current_abs_path, shared=True):
                virtual_size = lvm.get_lv_size(current_abs_path)

                if lvm.lv_exists(target_abs_path):
                    target_ps_uuid = get_primary_storage_uuid_from_install_path(struct.targetInstallPath)
                    raise Exception("found %s already exists on ps %s" %
                                    (target_abs_path, target_ps_uuid))
                lvm.create_lv_from_absolute_path(target_abs_path, virtual_size,
                                                     "%s::%s::%s" % (VOLUME_TAG, cmd.hostUuid, time.time()))
                lvm.active_lv(target_abs_path, lvm.LvmlockdLockType.SHARE)

        try:
            for struct in cmd.migrateVolumeStructs:
                target_abs_path = translate_absolute_path_from_install_path(struct.targetInstallPath)
                current_abs_path = translate_absolute_path_from_install_path(struct.currentInstallPath)

                with lvm.OperateLv(current_abs_path, shared=True):
                    bash.bash_errorout("cp %s %s" % (current_abs_path, target_abs_path))

            for struct in cmd.migrateVolumeStructs:
                target_abs_path = translate_absolute_path_from_install_path(struct.targetInstallPath)
                current_abs_path = translate_absolute_path_from_install_path(struct.currentInstallPath)
                with lvm.RecursiveOperateLv(current_abs_path, shared=True):
                    previous_ps_uuid = get_primary_storage_uuid_from_install_path(struct.currentInstallPath)
                    target_ps_uuid = get_primary_storage_uuid_from_install_path(struct.targetInstallPath)

                    current_backing_file = linux.qcow2_get_backing_file(current_abs_path)  # type: str
                    target_backing_file = current_backing_file.replace(previous_ps_uuid, target_ps_uuid)

                    if current_backing_file is not None and current_backing_file != "":
                        lvm.do_active_lv(target_backing_file, lvm.LvmlockdLockType.SHARE, False)
                        logger.debug("rebase %s to %s" % (target_abs_path, target_backing_file))
                        linux.qcow2_rebase_no_check(target_backing_file, target_abs_path)
                    if struct.compareQcow2:
                        bash.bash_errorout("time qemu-img compare %s %s" % (current_abs_path, target_abs_path))
        except Exception as e:
            for struct in cmd.migrateVolumeStructs:
                target_abs_path = translate_absolute_path_from_install_path(struct.targetInstallPath)
                if struct.currentInstallPath == struct.targetInstallPath:
                    logger.debug("current install path %s equals target %s, skip to delete" %
                                 (struct.currentInstallPath, struct.targetInstallPath))
                else:
                    logger.debug("error happened, delete lv %s" % target_abs_path)
                    lvm.delete_lv(target_abs_path, False)
            raise e
        finally:
            for struct in cmd.migrateVolumeStructs:
                target_abs_path = translate_absolute_path_from_install_path(struct.targetInstallPath)
                lvm.deactive_lv(target_abs_path)

        rsp.totalCapacity, rsp.availableCapacity = lvm.get_vg_size(cmd.vgUuid)
        return jsonobject.dumps(rsp)
Example #6
0
    def get_backing_file_path(self, req):
        cmd = jsonobject.loads(req[http.REQUEST_BODY])
        out = linux.qcow2_get_backing_file(cmd.path)
        rsp = GetBackingFileRsp()

        if out:
            rsp.backingFilePath = out
            rsp.size = os.path.getsize(out)

        return jsonobject.dumps(rsp)
Example #7
0
    def get_backing_file_path(self, req):
        cmd = jsonobject.loads(req[http.REQUEST_BODY])
        out = linux.qcow2_get_backing_file(cmd.path)
        rsp = GetBackingFileRsp()

        if out:
            rsp.backingFilePath = out
            rsp.size = os.path.getsize(out)

        return jsonobject.dumps(rsp)
Example #8
0
def do_active_lv(absolutePath, lockType, recursive):
    def handle_lv(lockType, fpath):
        if lockType > LvmlockdLockType.NULL:
            active_lv(fpath, lockType == LvmlockdLockType.SHARE)
        else:
            deactive_lv(fpath)

    handle_lv(lockType, absolutePath)

    if recursive is False or lockType is LvmlockdLockType.NULL:
        return

    while linux.qcow2_get_backing_file(absolutePath) != "":
        absolutePath = linux.qcow2_get_backing_file(absolutePath)
        if lockType == LvmlockdLockType.NULL:
            handle_lv(LvmlockdLockType.NULL, absolutePath)
        else:
            # activate backing files only in shared mode
            handle_lv(LvmlockdLockType.SHARE, absolutePath)
Example #9
0
def do_active_lv(absolutePath, lockType, recursive):
    def handle_lv(lockType, fpath):
        if lockType > LvmlockdLockType.NULL:
            active_lv(fpath, lockType == LvmlockdLockType.SHARE)
        else:
            deactive_lv(fpath)

    handle_lv(lockType, absolutePath)

    if recursive is False or lockType is LvmlockdLockType.NULL:
        return

    while linux.qcow2_get_backing_file(absolutePath) != "":
        absolutePath = linux.qcow2_get_backing_file(absolutePath)
        if lockType == LvmlockdLockType.NULL:
            handle_lv(LvmlockdLockType.NULL, absolutePath)
        else:
            # activate backing files only in shared mode
            handle_lv(LvmlockdLockType.SHARE, absolutePath)
    def do_active_lv(self, installPath, lockType, recursive):
        def handle_lv(lockType, fpath):
            if lockType > lvm.LvmlockdLockType.NULL:
                lvm.active_lv(fpath, lockType == lvm.LvmlockdLockType.SHARE)
            else:
                lvm.deactive_lv(fpath)

        install_abs_path = translate_absolute_path_from_install_path(installPath)
        handle_lv(lockType, install_abs_path)

        if recursive is False or lockType is lvm.LvmlockdLockType.NULL:
            return

        while linux.qcow2_get_backing_file(install_abs_path) != "":
            install_abs_path = linux.qcow2_get_backing_file(install_abs_path)
            if lockType == lvm.LvmlockdLockType.NULL:
                handle_lv(lvm.LvmlockdLockType.NULL, install_abs_path)
            else:
                # activate backing files only in shared mode
                handle_lv(lvm.LvmlockdLockType.SHARE, install_abs_path)
    def do_active_lv(self, installPath, lockType, recursive):
        def handle_lv(lockType, fpath):
            if lockType > lvm.LvmlockdLockType.NULL:
                lvm.active_lv(fpath, lockType == lvm.LvmlockdLockType.SHARE)
            else:
                lvm.deactive_lv(fpath)

        install_abs_path = translate_absolute_path_from_install_path(installPath)
        handle_lv(lockType, install_abs_path)

        if recursive is False or lockType is lvm.LvmlockdLockType.NULL:
            return

        while linux.qcow2_get_backing_file(install_abs_path) != "":
            install_abs_path = linux.qcow2_get_backing_file(install_abs_path)
            if lockType == lvm.LvmlockdLockType.NULL:
                handle_lv(lvm.LvmlockdLockType.NULL, install_abs_path)
            else:
                # activate backing files only in shared mode
                handle_lv(lvm.LvmlockdLockType.SHARE, install_abs_path)
Example #12
0
    def get_qcow2_reference(self, req):
        cmd = jsonobject.loads(req[http.REQUEST_BODY])
        out = shell.call('find %s -type f' % cmd.searchingDir)

        rsp = GetQCOW2ReferenceRsp()
        rsp.referencePaths = []
        real_path = os.path.realpath(cmd.path)
        for f in out.splitlines():
            backing_file = linux.qcow2_get_backing_file(f)
            if os.path.realpath(backing_file) == real_path:
                rsp.referencePaths.append(f)
        return jsonobject.dumps(rsp)
Example #13
0
    def get_qcow2_reference(self, req):
        cmd = jsonobject.loads(req[http.REQUEST_BODY])
        out = shell.call('find %s -type f' % cmd.searchingDir)

        rsp = GetQCOW2ReferenceRsp()
        rsp.referencePaths = []
        real_path = os.path.realpath(cmd.path)
        for f in out.splitlines():
            backing_file = linux.qcow2_get_backing_file(f)
            if os.path.realpath(backing_file) == real_path:
                rsp.referencePaths.append(f)
        return jsonobject.dumps(rsp)
    def do_active_lv(self,
                     installPath,
                     lockType,
                     recursive,
                     killProcess=False):
        def handle_lv(lockType, fpath):
            if lockType > lvm.LvmlockdLockType.NULL:
                lvm.active_lv(fpath, lockType == lvm.LvmlockdLockType.SHARE)
            else:
                try:
                    lvm.deactive_lv(fpath)
                except Exception as e:
                    if not killProcess:
                        return
                    qemus = lvm.find_qemu_for_lv_in_use(fpath)
                    if len(qemus) == 0:
                        return
                    for qemu in qemus:
                        if qemu.state != "running":
                            linux.kill_process(qemu.pid)
                    lvm.deactive_lv(fpath)

        install_abs_path = translate_absolute_path_from_install_path(
            installPath)
        handle_lv(lockType, install_abs_path)

        if recursive is False or lockType is lvm.LvmlockdLockType.NULL:
            return

        while linux.qcow2_get_backing_file(install_abs_path) != "":
            install_abs_path = linux.qcow2_get_backing_file(install_abs_path)
            if lockType == lvm.LvmlockdLockType.NULL:
                handle_lv(lvm.LvmlockdLockType.NULL, install_abs_path)
            else:
                # activate backing files only in shared mode
                handle_lv(lvm.LvmlockdLockType.SHARE, install_abs_path)
Example #15
0
    def verify_backing_file_chain(self, req):
        cmd = jsonobject.loads(req[http.REQUEST_BODY])
        for sp in cmd.snapshots:
            if not os.path.exists(sp.path):
                raise Exception('cannot find the file[%s]' % sp.path)

            if sp.parentPath and not os.path.exists(sp.parentPath):
                raise Exception('cannot find the backing file[%s]' % sp.parentPath)

            if sp.parentPath:
                out = linux.qcow2_get_backing_file(sp.path)

                if sp.parentPath != out:
                    raise Exception("resource[Snapshot or Volume, uuid:%s, path:%s]'s backing file[%s] is not equal to %s" %
                                (sp.snapshotUuid, sp.path, out, sp.parentPath))

        return jsonobject.dumps(AgentResponse())
Example #16
0
    def verify_backing_file_chain(self, req):
        cmd = jsonobject.loads(req[http.REQUEST_BODY])
        for sp in cmd.snapshots:
            if not os.path.exists(sp.path):
                raise Exception('cannot find the file[%s]' % sp.path)

            if sp.parentPath and not os.path.exists(sp.parentPath):
                raise Exception('cannot find the backing file[%s]' %
                                sp.parentPath)

            if sp.parentPath:
                out = linux.qcow2_get_backing_file(sp.path)

                if sp.parentPath != out:
                    raise Exception(
                        "resource[Snapshot or Volume, uuid:%s, path:%s]'s backing file[%s] is not equal to %s"
                        % (sp.snapshotUuid, sp.path, out, sp.parentPath))

        return jsonobject.dumps(AgentResponse())
    def rebase_volume_backing_file(self, req):
        cmd = jsonobject.loads(req[http.REQUEST_BODY])
        rsp = NfsRebaseVolumeBackingFileRsp()

        if not cmd.dstImageCacheTemplateFolderPath:
            qcow2s = shell.call("find %s -type f -regex '.*\.qcow2$'" % cmd.dstVolumeFolderPath)
        else:
            qcow2s = shell.call("find %s %s -type f -regex '.*\.qcow2$'" % (cmd.dstVolumeFolderPath, cmd.dstImageCacheTemplateFolderPath))

        for qcow2 in qcow2s.split():
            fmt = shell.call("qemu-img info %s | grep '^file format' | awk -F ': ' '{ print $2 }'" % qcow2)
            if fmt.strip() != "qcow2":
                continue
            backing_file = linux.qcow2_get_backing_file(qcow2)
            if backing_file == "":
                continue
            new_backing_file = backing_file.replace(cmd.srcPsMountPath, cmd.dstPsMountPath)
            linux.qcow2_rebase_no_check(new_backing_file, qcow2)
        return jsonobject.dumps(rsp)
    def get_qcow2_reference(self, req):
        cmd = jsonobject.loads(req[http.REQUEST_BODY])

        rsp = GetQCOW2ReferenceRsp()
        rsp.referencePaths = []
        real_path = get_absolute_path_from_install_path(cmd.path)
        for f in lvm.list_local_active_lvs(cmd.vgUuid):
            backing_file = linux.qcow2_direct_get_backing_file(f)
            if backing_file == real_path:
                rsp.referencePaths.append(f)
        for f in bash.bash_o(
                "ls -l /dev/drbd* | grep -E '^b' | awk '{print $NF}'"
        ).splitlines():
            f = f.strip()
            if f == "":
                continue
            try:
                if linux.qcow2_get_backing_file(f) == real_path:
                    rsp.referencePaths.append(f)
            except IOError:
                continue
        logger.debug("find qcow2 %s referencess: %s" %
                     (real_path, rsp.referencePaths))
        return jsonobject.dumps(rsp)
    def migrate_volumes(self, req):
        cmd = jsonobject.loads(req[http.REQUEST_BODY])
        rsp = AgentRsp()

        for struct in cmd.migrateVolumeStructs:
            target_abs_path = translate_absolute_path_from_install_path(struct.targetInstallPath)
            current_abs_path = translate_absolute_path_from_install_path(struct.currentInstallPath)
            with lvm.OperateLv(current_abs_path, shared=True):
                lv_size = lvm.get_lv_size(current_abs_path)

                if lvm.lv_exists(target_abs_path):
                    target_ps_uuid = get_primary_storage_uuid_from_install_path(struct.targetInstallPath)
                    raise Exception("found %s already exists on ps %s" %
                                    (target_abs_path, target_ps_uuid))
                lvm.create_lv_from_absolute_path(target_abs_path, lvm.getOriginalSize(lv_size),
                                                     "%s::%s::%s" % (VOLUME_TAG, cmd.hostUuid, time.time()))
                lvm.active_lv(target_abs_path, lvm.LvmlockdLockType.SHARE)

        try:
            for struct in cmd.migrateVolumeStructs:
                target_abs_path = translate_absolute_path_from_install_path(struct.targetInstallPath)
                current_abs_path = translate_absolute_path_from_install_path(struct.currentInstallPath)

                with lvm.OperateLv(current_abs_path, shared=True):
                    bash.bash_errorout("cp %s %s" % (current_abs_path, target_abs_path))

            for struct in cmd.migrateVolumeStructs:
                target_abs_path = translate_absolute_path_from_install_path(struct.targetInstallPath)
                current_abs_path = translate_absolute_path_from_install_path(struct.currentInstallPath)
                with lvm.RecursiveOperateLv(current_abs_path, shared=True):
                    previous_ps_uuid = get_primary_storage_uuid_from_install_path(struct.currentInstallPath)
                    target_ps_uuid = get_primary_storage_uuid_from_install_path(struct.targetInstallPath)

                    current_backing_file = linux.qcow2_get_backing_file(current_abs_path)  # type: str
                    target_backing_file = current_backing_file.replace(previous_ps_uuid, target_ps_uuid)

                    if struct.compareQcow2:
                        logger.debug("comparing qcow2 between %s and %s" % (current_abs_path, target_abs_path))
                        if not self.compare(current_abs_path, target_abs_path):
                            raise Exception("qcow2 %s and %s are not identical" % (current_abs_path, target_abs_path))
                        logger.debug("confirmed qcow2 %s and %s are identical" % (current_abs_path, target_abs_path))
                    if current_backing_file is not None and current_backing_file != "":
                        lvm.do_active_lv(target_backing_file, lvm.LvmlockdLockType.SHARE, False)
                        logger.debug("rebase %s to %s" % (target_abs_path, target_backing_file))
                        linux.qcow2_rebase_no_check(target_backing_file, target_abs_path)
        except Exception as e:
            for struct in cmd.migrateVolumeStructs:
                target_abs_path = translate_absolute_path_from_install_path(struct.targetInstallPath)
                if struct.currentInstallPath == struct.targetInstallPath:
                    logger.debug("current install path %s equals target %s, skip to delete" %
                                 (struct.currentInstallPath, struct.targetInstallPath))
                else:
                    logger.debug("error happened, delete lv %s" % target_abs_path)
                    lvm.delete_lv(target_abs_path, False)
            raise e
        finally:
            for struct in cmd.migrateVolumeStructs:
                target_abs_path = translate_absolute_path_from_install_path(struct.targetInstallPath)
                lvm.deactive_lv(target_abs_path)

        rsp.totalCapacity, rsp.availableCapacity = lvm.get_vg_size(cmd.vgUuid)
        return jsonobject.dumps(rsp)
Example #20
0
 def activate_and_remove(f):
     active_lv(f, shared=False)
     backing = linux.qcow2_get_backing_file(f)
     shell.check_run("lvremove -y -Stags={%s} %s" % (tag, f))
     return f
Example #21
0
def stream_body(task, fpath, entity, boundary):
    def _progress_consumer(total):
        task.downloadedSize = total

    @thread.AsyncThread
    def _do_import(task, fpath):
        shell.check_run("cat %s | rbd import --image-format 2 - %s" %
                        (fpath, task.tmpPath))

    while True:
        headers = cherrypy._cpreqbody.Part.read_headers(entity.fp)
        p = CustomPart(entity.fp, headers, boundary, fpath, _progress_consumer)
        if not p.filename:
            continue

        # start consumer
        _do_import(task, fpath)
        try:
            p.process()
        except Exception as e:
            logger.warn('process image %s failed: %s' %
                        (task.imageUuid, str(e)))
            pass
        finally:
            if p.wfd is not None:
                p.wfd.close()
        break

    if task.downloadedSize != task.expectedSize:
        task.fail('incomplete upload, got %d, expect %d' %
                  (task.downloadedSize, task.expectedSize))
        shell.run('rbd rm %s' % task.tmpPath)
        return

    file_format = None

    try:
        file_format = linux.get_img_fmt('rbd:' + task.tmpPath)
    except Exception as e:
        task.fail('upload image %s failed: %s' % (task.imageUuid, str(e)))
        return

    if file_format == 'qcow2':
        if linux.qcow2_get_backing_file('rbd:' + task.tmpPath):
            task.fail('Qcow2 image %s has backing file' % task.imageUuid)
            shell.run('rbd rm %s' % task.tmpPath)
            return

        conf_path = None
        try:
            with open('/etc/ceph/ceph.conf', 'r') as fd:
                conf = fd.read()
                conf = '%s\n%s\n' % (conf, 'rbd default format = 2')
                conf_path = linux.write_to_temp_file(conf)

            shell.check_run('%s -f qcow2 -O rbd rbd:%s rbd:%s:conf=%s' %
                            (qemu_img.subcmd('convert'), task.tmpPath,
                             task.dstPath, conf_path))
        except Exception as e:
            task.fail('cannot convert Qcow2 image %s to rbd' % task.imageUuid)
            logger.warn('convert image %s failed: %s',
                        (task.imageUuid, str(e)))
            return
        finally:
            shell.run('rbd rm %s' % task.tmpPath)
            if conf_path:
                os.remove(conf_path)
    else:
        shell.check_run('rbd mv %s %s' % (task.tmpPath, task.dstPath))

    task.success()
Example #22
0
 def activate_and_remove(f):
     active_lv(f, shared=False)
     backing = linux.qcow2_get_backing_file(f)
     shell.check_run("lvremove -y -Stags={%s} %s" % (tag, f))
     return f
Example #23
0
def stream_body(task, fpath, entity, boundary):
    def _progress_consumer(total):
        task.downloadedSize = total

    @thread.AsyncThread
    def _do_import(task, fpath):
        shell.check_run("cat %s | rbd import --image-format 2 - %s" % (fpath, task.tmpPath))

    while True:
        headers = cherrypy._cpreqbody.Part.read_headers(entity.fp)
        p = CustomPart(entity.fp, headers, boundary, fpath, _progress_consumer)
        if not p.filename:
            continue

        # start consumer
        _do_import(task, fpath)
        try:
            p.process()
        except Exception as e:
            logger.warn('process image %s failed: %s' % (task.imageUuid, str(e)))
            pass
        finally:
            if p.wfd is not None:
                p.wfd.close()
        break

    if task.downloadedSize != task.expectedSize:
        task.fail('incomplete upload, got %d, expect %d' % (task.downloadedSize, task.expectedSize))
        shell.run('rbd rm %s' % task.tmpPath)
        return

    file_format = None

    try:
        file_format = linux.get_img_fmt('rbd:'+task.tmpPath)
    except Exception as e:
        task.fail('upload image %s failed: %s' % (task.imageUuid, str(e)))
        return

    if file_format == 'qcow2':
        if linux.qcow2_get_backing_file('rbd:'+task.tmpPath):
            task.fail('Qcow2 image %s has backing file' % task.imageUuid)
            shell.run('rbd rm %s' % task.tmpPath)
            return

        conf_path = None
        try:
            with open('/etc/ceph/ceph.conf', 'r') as fd:
                conf = fd.read()
                conf = '%s\n%s\n' % (conf, 'rbd default format = 2')
                conf_path = linux.write_to_temp_file(conf)

            shell.check_run('qemu-img convert -f qcow2 -O rbd rbd:%s rbd:%s:conf=%s' % (task.tmpPath, task.dstPath, conf_path))
        except Exception as e:
            task.fail('cannot convert Qcow2 image %s to rbd' % task.imageUuid)
            logger.warn('convert image %s failed: %s', (task.imageUuid, str(e)))
            return
        finally:
            shell.run('rbd rm %s' % task.tmpPath)
            if conf_path:
                os.remove(conf_path)
    else:
        shell.check_run('rbd mv %s %s' % (task.tmpPath, task.dstPath))

    task.success()