Rename current_snapshot attribute, return it on creation, use pickle
This commit is contained in:
parent
e2ed27cbe4
commit
2c16fe793a
@ -5,6 +5,7 @@
|
|||||||
"""
|
"""
|
||||||
import logging
|
import logging
|
||||||
import datetime
|
import datetime
|
||||||
|
import pickle
|
||||||
|
|
||||||
from rbackup.hierarchy.hierarchy import Hierarchy
|
from rbackup.hierarchy.hierarchy import Hierarchy
|
||||||
from rbackup.hierarchy.snapshot import Snapshot
|
from rbackup.hierarchy.snapshot import Snapshot
|
||||||
@ -18,9 +19,16 @@ syslog = logging.getLogger(__name__)
|
|||||||
class Repository(Hierarchy):
|
class Repository(Hierarchy):
|
||||||
"""A class for interacting with a backup repository.
|
"""A class for interacting with a backup repository.
|
||||||
|
|
||||||
|
Repository is a mutable, stateful class for representing a
|
||||||
|
directory that contains backup data sequestered into snapshots
|
||||||
|
and a symlink to the most recently created snapshot.
|
||||||
|
* Each snapshot in a repository is unaware of one another,
|
||||||
|
this is the job of the repository to organize
|
||||||
|
* The only way snapshots are linked together is in files
|
||||||
|
that are hardlinked together
|
||||||
|
|
||||||
At the time of creation, the following is true about the class:
|
At the time of creation, the following is true about the class:
|
||||||
===============================================================
|
===============================================================
|
||||||
|
|
||||||
The current snapshot points to:
|
The current snapshot points to:
|
||||||
-------------------------------
|
-------------------------------
|
||||||
* None if the repository is empty
|
* None if the repository is empty
|
||||||
@ -31,14 +39,15 @@ class Repository(Hierarchy):
|
|||||||
----------
|
----------
|
||||||
* path (inherited from Hierarchy)
|
* path (inherited from Hierarchy)
|
||||||
* name (inherited from Hierarchy)
|
* name (inherited from Hierarchy)
|
||||||
* curr_snapshot - return either the most recent snapshot
|
* current_snapshot - either the most recent snapshot
|
||||||
before running create_snapshot() or the new snapshot
|
before running create_snapshot() or the new snapshot
|
||||||
created after running create_snapshot()
|
created after running create_snapshot()
|
||||||
* snapshots - return a list of snapshots stored in this repository
|
* snapshots - a list of snapshots stored in this repository
|
||||||
|
* snapshot_dir - the snapshot storage location of this repository
|
||||||
|
|
||||||
Methods
|
Methods
|
||||||
-------
|
-------
|
||||||
* create_snapshot() - create a new snapshot, then update curr_snapshot
|
* create_snapshot() - create a new snapshot, then update current_snapshot
|
||||||
|
|
||||||
Directory Structure
|
Directory Structure
|
||||||
-------------------
|
-------------------
|
||||||
@ -60,15 +69,17 @@ class Repository(Hierarchy):
|
|||||||
super().__init__(dest)
|
super().__init__(dest)
|
||||||
|
|
||||||
self._snapshot_index = 0
|
self._snapshot_index = 0
|
||||||
self._snapshots = [
|
|
||||||
Snapshot(s) for s in self.snapshot_dir.glob("*") if s.is_dir()
|
if self._metadata_path.exists():
|
||||||
]
|
with self._metadata_path.open(mode="rb") as metadata_file:
|
||||||
self._snapshots.sort()
|
self._snapshots = pickle.load(metadata_file)
|
||||||
|
else:
|
||||||
|
self._snapshots = []
|
||||||
|
|
||||||
try:
|
try:
|
||||||
self._curr_snapshot = self._snapshots[-1]
|
self._current_snapshot = self.snapshots[-1]
|
||||||
except IndexError:
|
except IndexError:
|
||||||
self._curr_snapshot = None
|
self._current_snapshot = None
|
||||||
|
|
||||||
def __len__(self):
|
def __len__(self):
|
||||||
"""Return the number of snapshots in this Repository."""
|
"""Return the number of snapshots in this Repository."""
|
||||||
@ -78,9 +89,17 @@ class Repository(Hierarchy):
|
|||||||
"""Retrieve a Snapshot at a certain index."""
|
"""Retrieve a Snapshot at a certain index."""
|
||||||
return self.snapshots[position]
|
return self.snapshots[position]
|
||||||
|
|
||||||
|
def __delitem__(self, s):
|
||||||
|
"""Delete a Snapshot in this Repository."""
|
||||||
|
raise NotImplementedError
|
||||||
|
|
||||||
def __iter__(self):
|
def __iter__(self):
|
||||||
return self
|
return self
|
||||||
|
|
||||||
|
def __contains__(self, snapshot):
|
||||||
|
"""Check whether a Snapshot is in this Repository."""
|
||||||
|
raise NotImplementedError
|
||||||
|
|
||||||
def __next__(self):
|
def __next__(self):
|
||||||
"""Return the next Snapshot in this Repository."""
|
"""Return the next Snapshot in this Repository."""
|
||||||
try:
|
try:
|
||||||
@ -114,7 +133,8 @@ class Repository(Hierarchy):
|
|||||||
>>> repo = Repository('/tmp')
|
>>> repo = Repository('/tmp')
|
||||||
>>> repo.snapshots
|
>>> repo.snapshots
|
||||||
[]
|
[]
|
||||||
>>> repo.create_snapshot()
|
>>> repo.create_snapshot() # doctest: +ELLIPSIS
|
||||||
|
<...Snapshot ... at 0x...>
|
||||||
>>> repo.snapshots # doctest: +ELLIPSIS
|
>>> repo.snapshots # doctest: +ELLIPSIS
|
||||||
[<...Snapshot ... at 0x...>]
|
[<...Snapshot ... at 0x...>]
|
||||||
|
|
||||||
@ -133,7 +153,8 @@ class Repository(Hierarchy):
|
|||||||
>>> repo = Repository('/tmp')
|
>>> repo = Repository('/tmp')
|
||||||
>>> repo.empty
|
>>> repo.empty
|
||||||
True
|
True
|
||||||
>>> repo.create_snapshot()
|
>>> repo.create_snapshot() # doctest: +ELLIPSIS
|
||||||
|
<...Snapshot ... at 0x...>
|
||||||
>>> repo.empty
|
>>> repo.empty
|
||||||
False
|
False
|
||||||
|
|
||||||
@ -142,24 +163,12 @@ class Repository(Hierarchy):
|
|||||||
return self.snapshots == []
|
return self.snapshots == []
|
||||||
|
|
||||||
@property
|
@property
|
||||||
def curr_snapshot(self):
|
def current_snapshot(self):
|
||||||
"""Return this Repository's current snapshot.
|
"""Return this Repository's current snapshot.
|
||||||
|
|
||||||
Example
|
|
||||||
-------
|
|
||||||
>>> repo = Repository('/tmp')
|
|
||||||
>>> repo.curr_snapshot
|
|
||||||
>>> repo.snapshots
|
|
||||||
[]
|
|
||||||
>>> repo.create_snapshot()
|
|
||||||
>>> repo.snapshots # doctest: +ELLIPSIS
|
|
||||||
[<...Snapshot ... at 0x...>]
|
|
||||||
>>> repo.curr_snapshot # doctest: +ELLIPSIS
|
|
||||||
<...Snapshot ... at 0x...>
|
|
||||||
|
|
||||||
:rtype: Snapshot object
|
:rtype: Snapshot object
|
||||||
"""
|
"""
|
||||||
return self._curr_snapshot
|
return self._current_snapshot
|
||||||
|
|
||||||
def create_snapshot(
|
def create_snapshot(
|
||||||
self, name=datetime.datetime.utcnow().isoformat().replace(":", "-")
|
self, name=datetime.datetime.utcnow().isoformat().replace(":", "-")
|
||||||
@ -169,26 +178,27 @@ class Repository(Hierarchy):
|
|||||||
This method is non-intrusive in that it will not
|
This method is non-intrusive in that it will not
|
||||||
make any changes in the filesystem when called.
|
make any changes in the filesystem when called.
|
||||||
|
|
||||||
Example
|
|
||||||
-------
|
|
||||||
>>> repo = Repository('/tmp')
|
|
||||||
>>> repo.snapshots
|
|
||||||
[]
|
|
||||||
>>> repo.curr_snapshot
|
|
||||||
>>> repo.create_snapshot()
|
|
||||||
>>> repo.curr_snapshot # doctest: +ELLIPSIS
|
|
||||||
<...Snapshot ... at 0x...>
|
|
||||||
|
|
||||||
:return: a new Snapshot object
|
:return: a new Snapshot object
|
||||||
"""
|
"""
|
||||||
syslog.debug("Creating snapshot")
|
syslog.debug("Creating snapshot")
|
||||||
path = self.snapshot_dir / f"snapshot-{name}"
|
|
||||||
|
|
||||||
self._curr_snapshot = Snapshot(path)
|
if not isinstance(name, str):
|
||||||
self.snapshots.append(self._curr_snapshot)
|
raise ValueError(f"{name} is not a valid type for a snapshot name")
|
||||||
|
|
||||||
|
snapshot_name = (
|
||||||
|
name
|
||||||
|
if name is not None
|
||||||
|
else datetime.datetime.utcnow().isoformat().replace(":", "-")
|
||||||
|
)
|
||||||
|
path = self.snapshot_dir / f"snapshot-{snapshot_name}"
|
||||||
|
|
||||||
|
self._current_snapshot = Snapshot(path)
|
||||||
|
self.snapshots.append(self._current_snapshot)
|
||||||
|
|
||||||
syslog.debug("Snapshot created")
|
syslog.debug("Snapshot created")
|
||||||
syslog.debug(f"Snapshot name: {self.curr_snapshot.name}")
|
syslog.debug(f"Snapshot name: {self.current_snapshot.name}")
|
||||||
|
|
||||||
|
return self._current_snapshot
|
||||||
|
|
||||||
|
|
||||||
# ========== Functions ==========
|
# ========== Functions ==========
|
||||||
|
Loading…
x
Reference in New Issue
Block a user