82 lines
2.6 KiB
Python
82 lines
2.6 KiB
Python
from __future__ import annotations
|
|
|
|
from datetime import timedelta
|
|
from uuid import UUID
|
|
|
|
from .disk import Disk
|
|
from .messages import CANNOT_FIND_BACKUP_DRIVE, ALREADY_IMPORTED, NOT_IMPORTED
|
|
from .misc import MAPPER_PATH, DISK_BY_UUID
|
|
from .commands.zfs import ZFS
|
|
from .dataset import Dataset
|
|
from .zfs_path import ZFSPath
|
|
from .commands.zpool import ZPool
|
|
|
|
|
|
class Pool:
|
|
"""Represents an internal pool."""
|
|
|
|
def __init__(self, name: str):
|
|
self._name = name
|
|
self._path: ZFSPath = ZFSPath.from_string(name)
|
|
|
|
@property
|
|
def datasets(self) -> list[Dataset]:
|
|
return ZFS.get_first_level_datasets(self)
|
|
|
|
@property
|
|
def name(self) -> str:
|
|
return self._name
|
|
|
|
|
|
class ExternalPool(Pool):
|
|
"""Represents an external pool."""
|
|
|
|
def __init__(self, name: str, disk: Disk):
|
|
super().__init__(name)
|
|
self._imported: bool = False
|
|
self._disk = disk
|
|
|
|
def import_(self) -> None:
|
|
"""Import a pool. Raise an error if the pool was previously imported."""
|
|
if self._imported:
|
|
raise ValueError(ALREADY_IMPORTED, self.name)
|
|
self._disk.decrypt()
|
|
ZPool.import_from_directory(self, MAPPER_PATH)
|
|
self._imported = True
|
|
|
|
def export(self) -> None:
|
|
"""Export a previously imported pool. Raise an error if the pool was not previously imported."""
|
|
if not self._imported:
|
|
raise ValueError(NOT_IMPORTED, self.name)
|
|
ZPool.export(self)
|
|
self._disk.encrypt()
|
|
self._imported = False
|
|
print(f"Exported {self.name}. Disk {self._disk.uuid} can be removed.")
|
|
|
|
def scrub(
|
|
self, skip_if_recently_scrubbed: bool, recent_scrub_timedelta: timedelta
|
|
) -> None:
|
|
print(f"Scrubbing {self._name}")
|
|
ZPool.scrub(
|
|
self,
|
|
skip_if_recently_scrubbed=skip_if_recently_scrubbed,
|
|
recent_scrub_timedelta=recent_scrub_timedelta,
|
|
)
|
|
|
|
@classmethod
|
|
def find_from_dict(cls, backup_pools: dict[str, UUID]) -> ExternalPool:
|
|
"""Using the dict in config.py, find the backup pool."""
|
|
present_uuids = [item.name for item in DISK_BY_UUID.iterdir()]
|
|
for pool_name, disk_uuid in backup_pools.items():
|
|
if str(disk_uuid) in present_uuids:
|
|
disk = Disk(disk_uuid, pool_name)
|
|
print(f"Found disk {pool_name}, {disk_uuid}")
|
|
return cls(pool_name, disk)
|
|
else:
|
|
raise FileNotFoundError(CANNOT_FIND_BACKUP_DRIVE)
|
|
|
|
def clean_old_snapshots(self) -> None:
|
|
print("Cleaning old snapshots")
|
|
for dataset in self.datasets:
|
|
dataset.clean_old_snapshots()
|