示例#1
0
def test_save_keep_other_options(tmpdir):
    path = create_lvm_conf(tmpdir, CONF)

    with lvmconf.LVMConfig(path) as conf:
        conf.setlist("devices", "filter", ["a|.*|"])
        conf.save()

    with lvmconf.LVMConfig(path) as conf:
        assert conf.getint("global", "use_lvmetad") == 1
示例#2
0
def test_set_empty_list(tmpdir):
    path = create_lvm_conf(tmpdir, CONF)

    with lvmconf.LVMConfig(path) as conf:
        conf.setlist("devices", "filter", [])
        conf.save()

    with lvmconf.LVMConfig(path) as conf:
        assert conf.getlist("devices", "filter") is None
示例#3
0
def test_remove(tmpdir):
    path = create_lvm_conf(tmpdir, CONF)

    with lvmconf.LVMConfig(path) as conf:
        conf.remove("devices", "filter")
        conf.save()

    with lvmconf.LVMConfig(path) as conf:
        assert conf.getlist("devices", "filter") is None
示例#4
0
def test_save_backup(tmpdir):
    path = create_lvm_conf(tmpdir, CONF)

    with lvmconf.LVMConfig(path) as conf:
        old_filter = conf.getlist("devices", "filter")
        conf.setlist("devices", "filter", ["a|.*|"])
        conf.save()

    with lvmconf.LVMConfig(path + ".augsave") as backup:
        assert backup.getlist("devices", "filter") == old_filter
示例#5
0
def test_save(tmpdir, data):
    path = create_lvm_conf(tmpdir, data)
    new_list = ["a|^/dev/sda2$|", "a|^/dev/sdb3$|", "r|.*|"]
    new_int = 0
    new_str = "ignore"

    with lvmconf.LVMConfig(path) as conf:
        conf.setlist("devices", "filter", new_list)
        conf.setint("global", "use_lvmetad", new_int)
        conf.setstr("activation", "missing_stripe_filler", new_str)
        conf.save()

    with lvmconf.LVMConfig(path) as conf:
        assert conf.getlist("devices", "filter") == new_list
        assert conf.getint("global", "use_lvmetad") == new_int
        assert conf.getstr("activation", "missing_stripe_filler") == new_str
示例#6
0
def _configure_devices_file(enable=True):
    """
    Configure lvm to use devices file or disable it.
    """
    enabled = 1 if enable else 0
    with lvmconf.LVMConfig() as config:
        config.setint("devices", "use_devicesfile", enabled)
        config.save()
示例#7
0
def _enabled():
    """
    Return True if lvm is configured to use devices file. Devices file itself
    is not needed to be configured as it has predefined value by lvm.
    """
    with lvmconf.LVMConfig() as config:
        use_devicesfile = config.getint("devices", "use_devicesfile") == 1
        return use_devicesfile
示例#8
0
def remove_filter():
    """
    Remove LVM filter from LVM configuration file.
    """
    with lvmconf.LVMConfig() as config:
        current_filter = config.getlist("devices", "filter")
        if current_filter:
            config.remove("devices", "filter")
            config.save()
示例#9
0
def test_read_empty(tmpdir):
    path = create_lvm_conf(tmpdir, "")
    with lvmconf.LVMConfig(path) as conf:
        # No option - and no type information
        assert conf.getlist("devices", "filter") is None
        assert conf.getint("devices", "filter") is None
        assert conf.getstr("devices", "filter") is None
        # Commented is same as no option
        assert conf.getlist("devices", "global_filter") is None
示例#10
0
def test_context_exit_error(tmpdir):
    # Raise if __exit__ fails.
    path = create_lvm_conf(tmpdir, "")

    def fail():
        raise RuntimeError

    with pytest.raises(RuntimeError):
        with lvmconf.LVMConfig(path) as conf:
            conf.close = fail
示例#11
0
def test_save_error(tmpdir):
    path = create_lvm_conf(tmpdir, CONF)

    with lvmconf.LVMConfig(path) as conf:
        conf.setlist("devices", "filter", ["a|.*|"])
        # Make save fail even when runing as root.
        os.unlink(path)
        os.mkdir(path)
        with pytest.raises(EnvironmentError):
            conf.save()
示例#12
0
def config_with_filter(args):
    mounts = lvmfilter.find_lvm_mounts()
    wanted_wwids = lvmfilter.find_wwids(mounts)
    current_wwids = mpathconf.read_blacklist()
    wanted_filter = lvmfilter.build_filter(mounts)
    with lvmconf.LVMConfig() as lvm_config:
        current_filter = lvm_config.getlist("devices", "filter")

    advice = lvmfilter.analyze(
        current_filter,
        wanted_filter,
        current_wwids,
        wanted_wwids)

    # This is the expected condition on a correctly configured host.
    if advice.action == lvmfilter.UNNEEDED:
        print("LVM filter is already configured for Vdsm")
        return

    # We need to configure LVM filter.

    _print_summary(mounts, current_filter, wanted_filter, advice.wwids, None)

    if advice.action == lvmfilter.CONFIGURE:

        if not args.assume_yes:
            if not common.confirm("Configure host? [yes,NO] "):
                return NEEDS_CONFIG

        mpathconf.configure_blacklist(advice.wwids)

        with lvmconf.LVMConfig() as config:
            config.setlist("devices", "filter", advice.filter)
            config.setint("devices", "use_devicesfile", 0)
            config.save()

        _print_success()

    elif advice.action == lvmfilter.RECOMMEND:
        _print_filter_warning()
        return CANNOT_CONFIG
示例#13
0
def test_context_propagate_user_error(tmpdir):
    # Raise user errors if __exit__ fails.
    path = create_lvm_conf(tmpdir, "")

    def fail():
        raise RuntimeError

    class UserError(Exception):
        pass

    with pytest.raises(UserError):
        with lvmconf.LVMConfig(path) as conf:
            conf.close = fail
            raise UserError
示例#14
0
def test_read_options(tmpdir):
    path = create_lvm_conf(tmpdir, CONF)
    with lvmconf.LVMConfig(path) as conf:
        # Correct type
        assert conf.getlist("devices", "filter") == ["a|^/dev/sda2$|", "r|.*|"]
        assert conf.getint("global", "use_lvmetad") == 1
        assert conf.getstr("activation", "missing_stripe_filler") == "error"

        # Wrong type
        assert conf.getstr("devices", "filter") is None
        assert conf.getint("devices", "filter") is None
        assert conf.getlist("global", "use_lvmetad") is None
        assert conf.getstr("global", "use_lvmetad") is None
        assert conf.getint("activation", "missing_stripe_filler") is None
        assert conf.getlist("activation", "missing_stripe_filler") is None
示例#15
0
def main(*args):
    """
    config-lvm-filter
    Configure LVM filter allowing LVM to access only the local storage
    needed by the hypervisor, but not shared storage owned by Vdsm.
    """

    print("Analyzing host...")

    mounts = lvmfilter.find_lvm_mounts()
    wanted_filter = lvmfilter.build_filter(mounts)

    with lvmconf.LVMConfig() as config:
        current_filter = config.getlist("devices", "filter")

    advice = lvmfilter.analyze(current_filter, wanted_filter)

    # This is the expected condition on a correctly configured host.
    if advice.action == lvmfilter.UNNEEDED:
        print("LVM filter is already configured for Vdsm")
        return

    # We need to configure LVM filter.

    print("Found these mounted logical volumes on this host:")
    print()

    for mnt in mounts:
        print("  logical volume: ", mnt.lv)
        print("  mountpoint:     ", mnt.mountpoint)
        print("  devices:        ", ", ".join(mnt.devices))
        print()

    print("This is the recommended LVM filter for this host:")
    print()
    print("  " + lvmfilter.format_option(wanted_filter))
    print()
    print("""\
This filter allows LVM to access the local devices used by the
hypervisor, but not shared storage owned by Vdsm. If you add a new
device to the volume group, you will need to edit the filter manually.
""")

    if current_filter:
        print("This is the current LVM filter:")
        print()
        print("  " + lvmfilter.format_option(current_filter))
        print()

    if advice.action == lvmfilter.CONFIGURE:

        if not confirm("Configure LVM filter? [yes,NO] "):
            return

        with lvmconf.LVMConfig() as config:
            config.setlist("devices", "filter", advice.filter)
            config.save()

        print("""\
Configuration completed successfully!

Please reboot to verify the LVM configuration.
""")

    elif advice.action == lvmfilter.RECOMMEND:

        print("""\
WARNING: The current LVM filter does not match the recommended filter,
Vdsm cannot configure the filter automatically.

Please edit /etc/lvm/lvm.conf and set the 'filter' option in the
'devices' section to the recommended value.

It is recommend to reboot after changing LVM filter.
""")
示例#16
0
def test_real_lvm_conf():
    with lvmconf.LVMConfig() as conf:
        assert conf.getint("global", "use_lvmetad") in (1, 0, None)
示例#17
0
def main(*args):
    """
    config-lvm-filter
    Configure LVM filter allowing LVM to access only the local storage
    needed by the hypervisor, but not shared storage owned by Vdsm.

    Return codes:
        0 - Successful completion.
        1 - Exception caught during operation.
        2 - Wrong arguments.
        3 - LVM filter configuration was found to be required but could not be
            completed since there is already another filter configured on the
            host.
        4 - User has chosen not to allow LVM filter reconfiguration, although
            found as required.
    """
    args = parse_args(args)

    print("Analyzing host...")

    mounts = lvmfilter.find_lvm_mounts()
    wanted_filter = lvmfilter.build_filter(mounts)
    wanted_wwids = lvmfilter.find_wwids(mounts)

    with lvmconf.LVMConfig() as config:
        current_filter = config.getlist("devices", "filter")

    current_wwids = mpathconf.read_blacklist()

    advice = lvmfilter.analyze(
        current_filter,
        wanted_filter,
        current_wwids,
        wanted_wwids)

    # This is the expected condition on a correctly configured host.
    if advice.action == lvmfilter.UNNEEDED:
        print("LVM filter is already configured for Vdsm")
        return

    # We need to configure LVM filter.

    print("Found these mounted logical volumes on this host:")
    print()

    for mnt in mounts:
        print("  logical volume: ", mnt.lv)
        print("  mountpoint:     ", mnt.mountpoint)
        print("  devices:        ", ", ".join(mnt.devices))
        print()

    print("This is the recommended LVM filter for this host:")
    print()
    print("  " + lvmfilter.format_option(wanted_filter))
    print()
    print("""\
This filter allows LVM to access the local devices used by the
hypervisor, but not shared storage owned by Vdsm. If you add a new
device to the volume group, you will need to edit the filter manually.
""")

    if current_filter:
        print("This is the current LVM filter:")
        print()
        print("  " + lvmfilter.format_option(current_filter))
        print()

    if advice.wwids:
        print("To use the recommended filter we need to add multipath")
        print("blacklist in /etc/multipath/conf.d/vdsm_blacklist.conf:")
        print()
        print(textwrap.indent(mpathconf.format_blacklist(advice.wwids), "  "))
        print()

    if advice.action == lvmfilter.CONFIGURE:

        if not args.assume_yes:
            if not common.confirm("Configure host? [yes,NO] "):
                return NEEDS_CONFIG

        mpathconf.configure_blacklist(advice.wwids)

        with lvmconf.LVMConfig() as config:
            config.setlist("devices", "filter", advice.filter)
            config.save()

        print("""\
Configuration completed successfully!

Please reboot to verify the configuration.
""")

    elif advice.action == lvmfilter.RECOMMEND:

        print("""\
WARNING: The current LVM filter does not match the recommended filter,
Vdsm cannot configure the filter automatically.

Please edit /etc/lvm/lvm.conf and set the 'filter' option in the
'devices' section to the recommended value.

Make sure /etc/multipath/conf.d/vdsm_blacklist.conf is set with the
recommended 'blacklist' section.

It is recommended to reboot to verify the new configuration.
""")
        return CANNOT_CONFIG