def rebaseVolumeRollback(cls, taskObj, sdUUID, srcImg, srcVol, dstFormat, srcParent, unsafe): """ Rebase volume rollback """ cls.log.info( 'rebase volume rollback (sdUUID=%s srcImg=%s srcVol=%s ' 'dstFormat=%s srcParent=%s)', sdUUID, srcImg, srcVol, dstFormat, srcParent) imageResourcesNamespace = sd.getNamespace(sc.IMAGE_NAMESPACE, sdUUID) with rm.acquireResource(imageResourcesNamespace, srcImg, rm.EXCLUSIVE): vol = sdCache.produce(sdUUID).produceVolume(srcImg, srcVol) vol.prepare(rw=True, chainrw=True, setrw=True) volumePath = vol.getVolumePath() backingVolPath = getBackingVolumePath(srcImg, srcParent) try: qemuimg.rebase(volumePath, backingVolPath, sc.fmt2str(vol.getFormat()), sc.fmt2str(int(dstFormat)), misc.parseBool(unsafe), vars.task.aborting) vol.setParent(srcParent) vol.recheckIfLeaf() except qemuimg.QImgError: cls.log.exception( 'cannot rollback rebase for volume %s on ' '%s', volumePath, backingVolPath) raise se.MergeVolumeRollbackError(srcVol) finally: vol.teardown(sdUUID, srcVol)
def rebase(self, backingVol, backingVolPath, backingFormat, unsafe, rollback): """ Rebase volume on top of new backing volume """ if rollback: pvol = self.getParentVolume() if not pvol: self.log.warn("Can't rebase volume %s, parent missing", self.volUUID) return name = "Merge volume: " + self.volUUID vars.task.pushRecovery( task.Recovery(name, "volume", "Volume", "rebaseVolumeRollback", [self.sdUUID, self.getImage(), self.volUUID, str(pvol.getFormat()), pvol.volUUID, str(True)])) volumePath = self.getVolumePath() try: qemuimg.rebase(volumePath, backingVolPath, fmt2str(self.getFormat()), fmt2str(backingFormat), unsafe, vars.task.aborting) except qemuimg.QImgError: self.log.exception('cannot rebase volume %s on %s', volumePath, backingVolPath) raise se.MergeSnapshotsError(self.volUUID) self.setParent(backingVol) self.recheckIfLeaf()
def rebaseVolumeRollback(cls, taskObj, sdUUID, srcImg, srcVol, dstFormat, srcParent, unsafe): """ Rebase volume rollback """ cls.log.info('rebase volume rollback (sdUUID=%s srcImg=%s srcVol=%s ' 'dstFormat=%s srcParent=%s)', sdUUID, srcImg, srcVol, dstFormat, srcParent) imageResourcesNamespace = sd.getNamespace( sdUUID, resourceFactories.IMAGE_NAMESPACE) with rmanager.acquireResource(imageResourcesNamespace, srcImg, rm.LockType.exclusive): vol = sdCache.produce(sdUUID).produceVolume(srcImg, srcVol) vol.prepare(rw=True, chainrw=True, setrw=True) volumePath = vol.getVolumePath() backingVolPath = getBackingVolumePath(srcImg, srcParent) try: qemuimg.rebase(volumePath, backingVolPath, fmt2str(vol.getFormat()), fmt2str(int(dstFormat)), misc.parseBool(unsafe), vars.task.aborting) vol.setParent(srcParent) vol.recheckIfLeaf() except qemuimg.QImgError: cls.log.exception('cannot rollback rebase for volume %s on ' '%s', volumePath, backingVolPath) raise se.MergeVolumeRollbackError(srcVol) finally: vol.teardown(sdUUID, srcVol)
def rebase(self, backingVol, backingVolPath, backingFormat, unsafe, rollback): """ Rebase volume on top of new backing volume """ if rollback: pvol = self.getParentVolume() if not pvol: self.log.warn("Can't rebase volume %s, parent missing", self.volUUID) return name = "Merge volume: " + self.volUUID vars.task.pushRecovery( task.Recovery(name, "volume", "Volume", "rebaseVolumeRollback", [ self.sdUUID, self.getImage(), self.volUUID, str(pvol.getFormat()), pvol.volUUID, str(True) ])) volumePath = self.getVolumePath() try: qemuimg.rebase(volumePath, backingVolPath, fmt2str(self.getFormat()), fmt2str(backingFormat), unsafe, vars.task.aborting) except qemuimg.QImgError: self.log.exception('cannot rebase volume %s on %s', volumePath, backingVolPath) raise se.MergeSnapshotsError(self.volUUID) self.setParent(backingVol) self.recheckIfLeaf()
def _update_qemu_metadata(dom, subchain): children = subchain.top_vol.getChildren() if children: # Top has children, update qcow metadata by rebasing -u child = dom.produceVolume(subchain.img_id, children[0]) log.info("Updating qemu metadata, rebasing volume %s into " "volume %s", child.volUUID, subchain.base_vol.volUUID) qemuimg.rebase(image=child.volumePath, backing=subchain.base_vol.volumePath, format=qemuimg.FORMAT.QCOW2, backingFormat=qemuimg.FORMAT.QCOW2, unsafe=True)
def _rebase_operation(base, child): backing = volume.getBackingVolumePath(base.imgUUID, base.volUUID) backing_format = sc.fmt2str(base.getFormat()) operation = qemuimg.rebase(image=child.volumePath, backing=backing, format=qemuimg.FORMAT.QCOW2, backingFormat=backing_format, unsafe=True) return operation
def test_read_bad_chain_raises(self): with namedTemporaryDir() as tmpdir: # Create a good chain. base_qcow2 = os.path.join(tmpdir, "base.qcow2") qemuimg.create(base_qcow2, "1m", qemuimg.FORMAT.QCOW2) top = os.path.join(tmpdir, "top.qcow2") qemuimg.create(top, "1m", qemuimg.FORMAT.QCOW2, backing=base_qcow2, backingFormat=qemuimg.FORMAT.QCOW2) # Create a broken chain using unsafe rebase with the wrong backing # format. base_raw = os.path.join(tmpdir, "base.raw") qemuimg.create(base_raw, "1m", qemuimg.FORMAT.RAW) operation = qemuimg.rebase(top, backing=base_raw, format=qemuimg.FORMAT.QCOW2, backingFormat=qemuimg.FORMAT.QCOW2, unsafe=True) operation.run() with self.assertRaises(cmdutils.Error): qemu_pattern_verify(top, qemuimg.FORMAT.QCOW2)