Пример #1
0
    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)
Пример #2
0
    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
Пример #3
0
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")
    ]
Пример #4
0
    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)