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)
def rebase_and_merge_snapshot(self, req): cmd = jsonobject.loads(req[http.REQUEST_BODY]) snapshots = cmd.snapshotInstallPaths count = len(snapshots) for i in range(count): if i+1 < count: target = snapshots[i] backing_file = snapshots[i+1] linux.qcow2_rebase_no_check(backing_file, target) latest = snapshots[0] rsp = RebaseAndMergeSnapshotsResponse() workspace_dir = os.path.dirname(cmd.workspaceInstallPath) if not os.path.exists(workspace_dir): os.makedirs(workspace_dir) try: linux.create_template(latest, cmd.workspaceInstallPath) rsp.size, rsp.actualSize = cmd.workspaceInstallPath self._set_capacity_to_response(cmd.uuid, rsp) except linux.LinuxError as e: logger.warn(linux.get_exception_stacktrace()) rsp.error = str(e) rsp.success = False return jsonobject.dumps(rsp)
def rebase_backing_files(self, req): cmd = jsonobject.loads(req[http.REQUEST_BODY]) for sp in cmd.snapshots: if sp.parentPath: linux.qcow2_rebase_no_check(sp.parentPath, sp.path) return jsonobject.dumps(AgentResponse())
def rebase_backing_files(self, req): cmd = jsonobject.loads(req[http.REQUEST_BODY]) for sp in cmd.snapshots: if sp.parentPath: linux.qcow2_rebase_no_check(sp.parentPath, sp.path) return jsonobject.dumps(AgentResponse())
def rebase_and_merge_snapshot(self, req): cmd = jsonobject.loads(req[http.REQUEST_BODY]) snapshots = cmd.snapshotInstallPaths count = len(snapshots) for i in range(count): if i+1 < count: target = snapshots[i] backing_file = snapshots[i+1] linux.qcow2_rebase_no_check(backing_file, target) latest = snapshots[0] rsp = RebaseAndMergeSnapshotsResponse() workspace_dir = os.path.dirname(cmd.workspaceInstallPath) if not os.path.exists(workspace_dir): os.makedirs(workspace_dir) try: linux.qcow2_create_template(latest, cmd.workspaceInstallPath) rsp.size, rsp.actualSize = cmd.workspaceInstallPath self._set_capacity_to_response(cmd.uuid, rsp) except linux.LinuxError as e: logger.warn(linux.get_exception_stacktrace()) rsp.error = str(e) rsp.success = False return jsonobject.dumps(rsp)
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)
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 merge_and_rebase_snapshot(self, req): cmd = jsonobject.loads(req[http.REQUEST_BODY]) snapshots = cmd.snapshotInstallPaths count = len(snapshots) for i in range(count): if i+1 < count: target = snapshots[i] backing_file = snapshots[i+1] linux.qcow2_rebase_no_check(backing_file, target) latest = snapshots[0] rsp = RebaseAndMergeSnapshotsRsp() workspace_dir = os.path.dirname(cmd.workspaceInstallPath) if not os.path.exists(workspace_dir): os.makedirs(workspace_dir) linux.qcow2_create_template(latest, cmd.workspaceInstallPath) rsp.size = os.path.getsize(cmd.workspaceInstallPath) return jsonobject.dumps(rsp)
def initialize_with_file(self, primary, src_path, backing=None, backing_fmt=None, skip_clear_bits=False): bash.bash_errorout("echo yes | drbdadm create-md %s --force" % self.name) self.up() if skip_clear_bits: return if not primary: self.clear_bits() else: self.promote() bash.bash_errorout('dd if=%s of=%s bs=1M oflag=direct' % (src_path, self.get_dev_path())) if backing: linux.qcow2_rebase_no_check(backing, self.get_dev_path(), backing_fmt=backing_fmt) self.demote()
def rebase_root_volume_to_backing_file(self, req): cmd = jsonobject.loads(req[http.REQUEST_BODY]) linux.qcow2_rebase_no_check(cmd.backingFilePath, cmd.rootVolumePath) return jsonobject.dumps(AgentResponse())
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)
def rebase_root_volume_to_backing_file(self, req): cmd = jsonobject.loads(req[http.REQUEST_BODY]) linux.qcow2_rebase_no_check(cmd.backingFilePath, cmd.rootVolumePath) return jsonobject.dumps(AgentResponse())