From: Vratislav Podzimek vpodzime@redhat.com
Related: rhbz#1166598 (cherry picked from commit b10e958a2d1a3a115a0de272c6ecb3175d3f7f4c) --- pyanaconda/storage_utils.py | 62 +++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 62 insertions(+)
diff --git a/pyanaconda/storage_utils.py b/pyanaconda/storage_utils.py index 342dfb5..7289bc5 100644 --- a/pyanaconda/storage_utils.py +++ b/pyanaconda/storage_utils.py @@ -382,3 +382,65 @@ def bound_size(size, device, old_size): size = min_size
return size + +class StorageSnapshot(object): + """R/W snapshot of storage (i.e. a :class:`blivet.Blivet` instance)""" + + def __init__(self, storage=None): + """ + Create new instance of the class + + :param storage: if given, its snapshot is created + :type storage: :class:`blivet.Blivet` + """ + if storage: + self._storage_snap = storage.copy() + else: + self._storage_snap = None + + @property + def storage(self): + return self._storage_snap + + @property + def created(self): + return bool(self._storage_snap) + + def create_snapshot(self, storage): + """Create (and save) snapshot of storage""" + + self._storage_snap = storage.copy() + + def dispose_snapshot(self): + """ + Dispose (unref) the snapshot + + .. note:: + + In order to free the memory taken by the snapshot, all references + returned by :property:`self.storage` have to be unrefed too. + """ + self._storage_snap = None + + def reset_to_snapshot(self, storage, dispose=False): + """ + Reset storage to snapshot (**modifies :param:`storage` in place**) + + :param storage: :class:`blivet.Blivet` instance to reset to the created snapshot + :param bool dispose: whether to dispose the snapshot after reset or not + :raises ValueError: if no snapshot is available (was not created before) + """ + if not self.created: + raise ValueError("No snapshot created, cannot reset") + + # we need to create a new copy from the snapshot first -- simple + # assignment from the snapshot would result in snapshot being modified + # by further changes of 'storage' + new_copy = self._storage_snap.copy() + storage.devicetree = new_copy.devicetree + storage.roots = new_copy.roots + storage.fsset = new_copy.fsset + + if dispose: + self.dispose_snapshot() +