async def target_unmatched_snapshots(self, direction, source_datasets, target_dataset, transport, ssh_credentials): fake_replication_task = types.SimpleNamespace() fake_replication_task.source_datasets = source_datasets fake_replication_task.target_dataset = target_dataset datasets = { source_dataset: get_target_dataset(fake_replication_task, source_dataset) for source_dataset in source_datasets } try: local_shell = LocalShell() async with self._get_zettarepl_shell( transport, ssh_credentials) as remote_shell: if direction == "PUSH": source_shell = local_shell target_shell = remote_shell else: source_shell = remote_shell target_shell = local_shell target_datasets = set(list_datasets(target_shell)) datasets = { source_dataset: target_dataset for source_dataset, target_dataset in datasets.items() if target_dataset in target_datasets } source_snapshots = group_snapshots_by_datasets( await self.middleware.run_in_thread( multilist_snapshots, source_shell, [(dataset, False) for dataset in datasets.keys()])) target_snapshots = group_snapshots_by_datasets( await self.middleware.run_in_thread( multilist_snapshots, target_shell, [(dataset, False) for dataset in datasets.values()])) except Exception as e: raise CallError(repr(e)) errors = {} for source_dataset, target_dataset in datasets.items(): unmatched_snapshots = list( set(target_snapshots.get(target_dataset, [])) - set(source_snapshots.get(source_dataset, []))) if unmatched_snapshots: errors[target_dataset] = unmatched_snapshots return errors
def get_empty_snapshots_for_deletion(shell: Shell, tasks_with_snapshot_names: [(PeriodicSnapshotTask, str)]): datasets = list_datasets(shell) snapshots = defaultdict(list) for task, snapshot_name in tasks_with_snapshot_names: for snapshot in get_task_snapshots(datasets, task, snapshot_name): snapshots[snapshot].append(task.allow_empty) empty_snapshots = [] for snapshot in [snapshot for snapshot, allow_empty in snapshots.items() if not any(allow_empty)]: try: if is_empty_snapshot(shell, snapshot): empty_snapshots.append(snapshot) except ExecException as e: logger.warning("Failed to check if snapshot %r is empty, assuming it is not. Error: %r", snapshot, e) return empty_snapshots
async def list_datasets(self, transport, ssh_credentials=None): try: return list_datasets(await self._get_zettarepl_shell( transport, ssh_credentials)) except Exception as e: raise CallError(repr(e))