from __future__ import annotations from datetime import timedelta from uuid import UUID from .disk import Disk 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("Cannot import, 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("Cannot export, 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("Could not find a backup drive") def clean_old_snapshots(self) -> None: print("Cleaning old snapshots") for dataset in self.datasets: dataset.clean_old_snapshots()