Beispiel #1
0
def start_backups(parsed_args, *args, **kwargs):
    vir_event_loop_native_start()

    config = get_setup_config()
    conn = get_setup_conn(config)
    callbacks_registrer = DomExtSnapshotCallbackRegistrer(conn)

    if config.get("groups", None):
        groups = build_all_or_selected_groups(
            config, conn, callbacks_registrer, parsed_args.groups
        )
        main_group = build_main_backup_group(groups)
        nb_threads = config.get("threads", 0)
        try:
            try:
                with callbacks_registrer:
                    if nb_threads > 1 or nb_threads == 0:
                        main_group.start_multithread(nb_threads=nb_threads)
                    else:
                        main_group.start()
            except BackupsFailureInGroupError as e:
                logger.error(e)
                sys.exit(2)
        except KeyboardInterrupt:
            print("Cancelled…")
            sys.exit(1)
Beispiel #2
0
def test_groups_from_dict_multiple_groups(build_mock_libvirtconn_filled):
    """
    Test match_domains_from_config with a str pattern
    """
    conn = build_mock_libvirtconn_filled
    callbacks_registrer = DomExtSnapshotCallbackRegistrer(conn)
    groups_config = {
        "test0": {
            "target": "/mnt/test0",
            "packager": "tar",
            "hosts": [
                "matching2",
            ],
        },
        "test1": {
            "target": "/mnt/test1",
            "hosts": ["matching", "a"],
        },
    }

    groups = tuple(groups_from_dict(groups_config, conn, callbacks_registrer))
    assert len(groups) == 2
    group0, group1 = groups

    assert sorted((group0.name, group1.name)) == ["test0", "test1"]
Beispiel #3
0
def test_groups_from_sanitize_dict_all_config_group_param(
    build_mock_libvirtconn_filled,
):
    """
    Test with the example config, containing every possible parameter

    Related to issue #13
    """
    conn = build_mock_libvirtconn_filled
    callbacks_registrer = DomExtSnapshotCallbackRegistrer(conn)
    groups_config = {
        "test": {
            "target": "/mnt/test",
            "packager": "tar",
            "autostart": True,
            "hourly": 1,
            "daily": 3,
            "weekly": 2,
            "monthly": 5,
            "yearly": 1,
            "hosts": [
                {"host": r"r:^matching\d?$", "disks": ["vda", "vdb"]},
                "!matching2",
                "nonexisting",
            ],
        },
    }
    group = next(iter(groups_from_dict(groups_config, conn, callbacks_registrer)))

    for prop in ("hourly", "daily", "weekly", "monthly", "yearly"):
        assert prop not in group.default_bak_param
    def test_clean_broken(self, build_backup_directory, build_mock_domain,
                          build_mock_libvirtconn, mocker):
        build_mock_libvirtconn._domains.append(build_mock_domain)
        callbacks_registrer = DomExtSnapshotCallbackRegistrer(
            build_mock_libvirtconn)
        backup_dir = build_backup_directory["backup_dir"]
        group = CompleteBackupGroup(name="test",
                                    backup_dir=str(backup_dir),
                                    hosts=["r:.*"],
                                    conn=build_mock_libvirtconn,
                                    callbacks_registrer=callbacks_registrer)

        dombkup = DomBackup(dom=build_mock_domain,
                            target_dir=str(
                                backup_dir.mkdir(build_mock_domain.name())),
                            callbacks_registrer=callbacks_registrer)
        dombkup.pending_info["domain_name"] = build_mock_domain.name()
        dombkup.pending_info["date"] = 0
        dombkup._dump_pending_info()

        group.scan_backup_dir()
        nb_initial_backups = sum(len(b) for b in group.broken_backups.values())
        assert nb_initial_backups == 1

        broken_backup = group.broken_backups[build_mock_domain.name()][0]
        mocker.spy(broken_backup, "clean_aborted")

        group.clean_broken_backups()
        assert not group.broken_backups[build_mock_domain.name()]
        assert broken_backup.clean_aborted.called
Beispiel #5
0
def test_groups_from_dict(build_mock_libvirtconn_filled):
    """
    Test groups_from_dict with only one group
    """
    conn = build_mock_libvirtconn_filled
    callbacks_registrer = DomExtSnapshotCallbackRegistrer(conn)
    groups_config = {
        "test": {
            "target": "/mnt/test",
            "packager": "tar",
            "hosts": [
                {"host": r"r:^matching\d?$", "disks": ["vda", "vdb"]},
                "!matching2",
                "nonexisting",
            ],
        },
    }

    groups = tuple(groups_from_dict(groups_config, conn, callbacks_registrer))
    assert len(groups) == 1
    test_group = groups[0]

    assert test_group.default_bak_param["backup_dir"] == "/mnt/test"
    assert test_group.default_bak_param["packager"] == "tar"

    dombackups = test_group.backups
    assert len(dombackups) == 1

    matching_backup = dombackups[0]
    assert matching_backup.dom.name() == "matching"
    assert tuple(sorted(matching_backup.disks.keys())) == ("vda", "vdb")
Beispiel #6
0
def test_groups_from_dict_multiple_filters(build_mock_libvirtconn_filled):
    """
    Test groups_from_dict with only one group, multiple filters

    Linked to issue #28
    """
    conn = build_mock_libvirtconn_filled
    callbacks_registrer = DomExtSnapshotCallbackRegistrer(conn)
    groups_config = {
        "test": {
            "target": "/mnt/test",
            "packager": "tar",
            "hosts": [
                {"host": "matching", "disks": ["vda", "vdb"]},
                {"host": "matching2", "disks": ["vda"]},
            ],
        },
    }

    groups = tuple(groups_from_dict(groups_config, conn, callbacks_registrer))

    dombackups = groups[0].backups

    assert dombackups[0].dom.name() == "matching"
    assert tuple(sorted(dombackups[0].disks.keys())) == ("vda", "vdb")
    assert dombackups[1].dom.name() == "matching2"
    assert tuple(sorted(dombackups[1].disks.keys())) == ("vda",)
Beispiel #7
0
def list_groups(parsed_args, *args, **kwargs):
    vir_event_loop_native_start()
    config = get_setup_config()
    conn = get_setup_conn(config)
    callbacks_registrer = DomExtSnapshotCallbackRegistrer(conn)

    complete_groups = {g.name: g for g in get_usable_complete_groups(config)}
    if parsed_args.list_all:
        backups_by_group = _get_all_hosts_and_bak_by_groups(
            parsed_args.groups, config, conn, callbacks_registrer
        )
    else:
        backups_by_group = {}
        for cmplgroup in complete_groups.values():
            cmplgroup.scan_backup_dir()
            backups_by_group[cmplgroup.name] = cmplgroup.backups.copy()
    for group_name, dom_backups in backups_by_group.items():
        if parsed_args.domains_names:
            return list_detailed_backups_for_domain(
                complete_groups[group_name],
                parsed_args.domains_names,
                short=parsed_args.short,
            )
        print(" {}\n{}\n".format(group_name, (2 + len(group_name)) * "="))
        print(
            "Total backups: {} hosts, {} backups".format(
                len(dom_backups), sum(len(backups) for backups in dom_backups.values())
            )
        )
        if not parsed_args.short:
            print("Hosts:")
            # TODO: Should also print hosts matching in libvirt but not backup
            # yet
            for dom, backups in sorted(dom_backups.items()):
                print("\t{}: {} backup(s)".format(dom, len(backups)))
Beispiel #8
0
    def compare_parsed_groups_with_complete(self, parsed_groups, config):
        """
        :param additional_domains: domains without backup, by group, needed to
                                   be printed in the listing
        """
        callbacks_registrer = DomExtSnapshotCallbackRegistrer(self.conn)
        complete_groups = {
            g.name: g
            for g in get_usable_complete_groups(config)
        }
        pending_groups = {
            g.name: g
            for g in build_all_or_selected_groups(config, self.conn,
                                                  callbacks_registrer)
        }

        for parsed_group, parsed_values in parsed_groups.items():
            cgroup = complete_groups[parsed_group]
            cgroup.scan_backup_dir()
            pgroup = pending_groups[parsed_group]

            expected_domains = set(cgroup.backups.keys())
            expected_domains.update(set(b.dom.name() for b in pgroup.backups))
            assert sorted(parsed_values.keys()) == sorted(expected_domains)

            for parsed_domain, parsed_backups in parsed_values.items():
                assert parsed_backups == len(
                    cgroup.backups.get(parsed_domain, []))
Beispiel #9
0
def get_uncompressed_dombackup(build_mock_domain, build_mock_libvirtconn):
    callbacks_registrer = DomExtSnapshotCallbackRegistrer(
        build_mock_libvirtconn)
    return DomBackup(dom=build_mock_domain,
                     dev_disks=("vda", ),
                     compression=None,
                     callbacks_registrer=callbacks_registrer)
Beispiel #10
0
def clean_backups(parsed_args, *args, **kwargs):
    vir_event_loop_native_start()

    config = get_setup_config()
    conn = get_setup_conn(config)
    callbacks_registrer = DomExtSnapshotCallbackRegistrer(conn)
    groups = get_usable_complete_groups(config, parsed_args.groups, conn,
                                        callbacks_registrer)

    with callbacks_registrer:
        for g in groups:
            g.scan_backup_dir()
            current_group_config = config.get_groups()[g.name]
            clean_params = {
                "hourly": current_group_config.get("hourly", "*"),
                "daily": current_group_config.get("daily", "*"),
                "weekly": current_group_config.get("weekly", "*"),
                "monthly": current_group_config.get("monthly", "*"),
                "yearly": current_group_config.get("yearly", "*"),
            }
            if not parsed_args.broken_only:
                print("Backups removed for group {}: {}".format(
                    g.name or "Undefined", len(g.clean(**clean_params))))
            if not parsed_args.no_broken:
                print("Broken backups removed for group {}: {}".format(
                    g.name or "Undefined", len(g.clean_broken_backups())))
Beispiel #11
0
def restore_backup(parsed_args, *args, **kwargs):
    vir_event_loop_native_start()

    config = get_setup_config()
    conn = get_setup_conn(config)
    callbacks_registrer = DomExtSnapshotCallbackRegistrer(conn)
    try:
        group = next(
            get_usable_complete_groups(config, [parsed_args.group], conn,
                                       callbacks_registrer))
    except StopIteration:
        logger.critical("Group {} not found".format(parsed_args.group))
        sys.exit(1)
    group.scan_backup_dir()

    domain_name = parsed_args.domain_name
    target_dir = parsed_args.target_dir
    target_date = arrow.get(parsed_args.date) if parsed_args.date else None

    if target_date:
        backup = group.get_backup_at_date(domain_name, target_date)
    else:
        try:
            backup = group.backups[domain_name][-1]
        except KeyError:
            raise BackupNotFoundError

    with callbacks_registrer:
        backup.restore_to(target_dir)
Beispiel #12
0
def get_backup_group(build_mock_domain, build_mock_libvirtconn):
    callbacks_registrer = DomExtSnapshotCallbackRegistrer(build_mock_libvirtconn)
    return BackupGroup(
        build_mock_libvirtconn,
        domlst=((build_mock_domain, None),),
        callbacks_registrer=callbacks_registrer,
    )
Beispiel #13
0
def get_uncompressed_dombackup(build_mock_domain, build_mock_libvirtconn):
    callbacks_registrer = DomExtSnapshotCallbackRegistrer(build_mock_libvirtconn)
    return DomBackup(
        dom=build_mock_domain,
        dev_disks=("vda",),
        packager="directory",
        callbacks_registrer=callbacks_registrer,
    )
Beispiel #14
0
def get_compressed_dombackup(build_mock_domain, build_mock_libvirtconn):
    callbacks_registrer = DomExtSnapshotCallbackRegistrer(build_mock_libvirtconn)
    return DomBackup(
        dom=build_mock_domain,
        dev_disks=("vda",),
        packager="tar",
        packager_opts={"compression": "xz", "compression_lvl": 4},
        callbacks_registrer=callbacks_registrer,
    )
Beispiel #15
0
def build_backup_group(conn, *group_args, **group_kwargs):
    callbacks_registrer = DomExtSnapshotCallbackRegistrer(conn)
    return BackupGroup(*group_args,
                       callbacks_registrer=callbacks_registrer,
                       **group_kwargs)
Beispiel #16
0
def build_dombackup(dom, *dombackup_args, **dombackup_kwargs):
    callbacks_registrer = DomExtSnapshotCallbackRegistrer(dom._conn)
    return DomBackup(dom,
                     *dombackup_args,
                     callbacks_registrer=callbacks_registrer,
                     **dombackup_kwargs)
Beispiel #17
0
def get_dombackup(build_mock_domain, build_mock_libvirtconn):
    callbacks_registrer = DomExtSnapshotCallbackRegistrer(
        build_mock_libvirtconn)
    return DomBackup(build_mock_domain,
                     callbacks_registrer=callbacks_registrer)