def _run_remote_retention(self, now: datetime): push_replication_tasks = list( filter(self._is_push_replication_task, select_by_class(ReplicationTask, self.tasks))) local_snapshots_grouped = group_snapshots_by_datasets( multilist_snapshots( self.local_shell, replication_tasks_source_datasets_queries( push_replication_tasks))) for transport, replication_tasks in self._transport_for_replication_tasks( push_replication_tasks): shell = self._get_shell(transport) remote_snapshots = multilist_snapshots( shell, [(replication_task.target_dataset, replication_task.recursive) for replication_task in replication_tasks]) remote_snapshots_grouped = group_snapshots_by_datasets( remote_snapshots) owners = [ ExecutedReplicationTaskSnapshotOwner(now, replication_task, local_snapshots_grouped, remote_snapshots_grouped) for replication_task in replication_tasks ] snapshots_to_destroy = calculate_snapshots_to_remove( owners, remote_snapshots) logger.info("Retention on transport %r destroying snapshots: %r", transport, snapshots_to_destroy) destroy_snapshots(shell, snapshots_to_destroy)
def _run_remote_retention(self, now: datetime): push_replication_tasks = list( filter(self._is_push_replication_task, select_by_class(ReplicationTask, self.tasks))) local_snapshots_grouped = group_snapshots_by_datasets( multilist_snapshots( self.local_shell, replication_tasks_source_datasets_queries( push_replication_tasks))) for transport, replication_tasks in self._transport_for_replication_tasks( push_replication_tasks): shell = self._get_retention_shell(transport) remote_snapshots_queries = [ (replication_task.target_dataset, replication_task.recursive) for replication_task in replication_tasks ] try: # Prevent hanging remote from breaking all the replications with ShellTimeoutContext(3600): remote_snapshots = multilist_snapshots( shell, remote_snapshots_queries) except Exception as e: logger.warning( "Remote retention failed on %r: error listing snapshots: %r", transport, e) continue remote_snapshots_grouped = group_snapshots_by_datasets( remote_snapshots) owners = [ ExecutedReplicationTaskSnapshotOwner(now, replication_task, local_snapshots_grouped, remote_snapshots_grouped) for replication_task in replication_tasks ] snapshots_to_destroy = calculate_snapshots_to_remove( owners, remote_snapshots) logger.info("Retention on %r destroying snapshots: %r", transport, snapshots_to_destroy) try: # Prevent hanging remote from breaking all the replications with ShellTimeoutContext(3600): destroy_snapshots(shell, snapshots_to_destroy) except Exception as e: logger.warning( "Remote retention failed on %r: error destroying snapshots: %r", transport, e) continue
def test__calculate_snapshots_to_remove(): assert calculate_snapshots_to_remove([ PeriodicSnapshotTaskSnapshotOwner( datetime(2019, 5, 30, 21, 52), Mock(dataset="dst/work", recursive=False, exclude=[], lifetime=timedelta(days=14), naming_schema="auto-%Y-%m-%d_%H-%M")), PeriodicSnapshotTaskSnapshotOwner( datetime(2019, 5, 30, 21, 52), Mock(dataset="dst/work", recursive=False, exclude=[], lifetime=timedelta(hours=1), naming_schema="snap%d%m%Y%H%M")), ], [Snapshot("dst/work", "snap300520191856")]) == [ Snapshot("dst/work", "snap300520191856") ]
def _run_local_retention(self, now: datetime): periodic_snapshot_tasks = select_by_class(PeriodicSnapshotTask, self.tasks) replication_tasks = select_by_class(ReplicationTask, self.tasks) push_replication_tasks_that_can_hold = [ replication_task for replication_task in replication_tasks if replication_task.hold_pending_snapshots ] pull_replications_tasks = list( filter(self._is_pull_replication_task, replication_tasks)) local_snapshots_queries = [] local_snapshots_queries.extend([ (periodic_snapshot_task.dataset, periodic_snapshot_task.recursive) for periodic_snapshot_task in periodic_snapshot_tasks ]) local_snapshots_queries.extend( replication_tasks_source_datasets_queries( push_replication_tasks_that_can_hold)) local_snapshots_queries.extend([ (replication_task.target_dataset, replication_task.recursive) for replication_task in pull_replications_tasks ]) local_snapshots = multilist_snapshots(self.local_shell, local_snapshots_queries) local_snapshots_grouped = group_snapshots_by_datasets(local_snapshots) owners = [] owners.extend([ PeriodicSnapshotTaskSnapshotOwner(now, periodic_snapshot_task) for periodic_snapshot_task in periodic_snapshot_tasks ]) # These are always only PUSH replication tasks for transport, replication_tasks in self._transport_for_replication_tasks( push_replication_tasks_that_can_hold): shell = self._get_retention_shell(transport) owners.extend( pending_push_replication_task_snapshot_owners( local_snapshots_grouped, shell, replication_tasks)) for transport, replication_tasks in self._transport_for_replication_tasks( pull_replications_tasks): shell = self._get_retention_shell(transport) remote_snapshots_queries = replication_tasks_source_datasets_queries( replication_tasks) try: remote_snapshots = multilist_snapshots( shell, remote_snapshots_queries) except Exception as e: logger.warning( "Local retention failed: error listing snapshots on %r: %r", transport, e) return remote_snapshots_grouped = group_snapshots_by_datasets( remote_snapshots) owners.extend([ executed_pull_replication_task_snapshot_owner( now, replication_task, remote_snapshots_grouped, local_snapshots_grouped) for replication_task in replication_tasks ]) snapshots_to_destroy = calculate_snapshots_to_remove( owners, local_snapshots) logger.info("Retention destroying local snapshots: %r", snapshots_to_destroy) destroy_snapshots(self.local_shell, snapshots_to_destroy)