Ejemplo n.º 1
0
def veth_pair(prefix='veth_', max_length=15):
    """
    Yield a pair of veth devices. This assumes root privileges (currently
    required by all tests anyway).

    Both sides of the pair have a pseudo-random suffix (e.g. veth_m6Lz7uMK9c).
    """
    left_side = random_iface_name(prefix, max_length)
    right_side = random_iface_name(prefix, max_length)
    try:
        linkAdd(left_side, linkType='veth', args=('peer', 'name', right_side))
        if nmstate.is_nmstate_backend():
            cmd.exec_sync(['nmcli', 'dev', 'set', left_side, 'managed', 'yes'])
            cmd.exec_sync(
                ['nmcli', 'dev', 'set', right_side, 'managed', 'yes'])
    except IPRoute2Error as e:
        pytest.skip('Failed to create a veth pair: %s', e)
    try:
        yield left_side, right_side
    finally:
        # the peer device is removed by the kernel
        linkDel(left_side)
        if nmstate.is_nmstate_backend():
            cmd.exec_sync(['nmcli', 'con', 'del', left_side])
            cmd.exec_sync(['nmcli', 'con', 'del', right_side])
Ejemplo n.º 2
0
    def test_get_bonding_options(self, bond_module):
        INTERVAL = '12345'
        bond_name = random_iface_name()

        if not bond_module:
            pytest.skip('Bonding is not available')

        with open(BONDING_MASTERS, 'w') as bonds:
            bonds.write('+' + bond_name)
            bonds.flush()

            try:  # no error is anticipated but let's make sure we can clean up
                assert self._bond_opts_without_mode(bond_name) == {}, (
                    'This test fails when a new bonding option is added to '
                    'the kernel. Please run vdsm-tool dump-bonding-options` '
                    'and retest.')

                with open(bonding.BONDING_OPT % (bond_name, 'miimon'),
                          'w') as opt:
                    opt.write(INTERVAL)

                assert self._bond_opts_without_mode(bond_name) == {
                    'miimon': INTERVAL
                }

            finally:
                bonds.write('-' + bond_name)
Ejemplo n.º 3
0
def bond_device(slaves, prefix='bond', max_length=11):
    check_sysfs_bond_permission()
    name = random_iface_name(prefix, max_length)
    with linkbond.Bond(name, slaves) as bond:
        bond.create()
        yield bond.master
    bond.destroy()
Ejemplo n.º 4
0
def _atomic_copytree(srcpath, dstpath, remove_src=False):
    """
    Copy srcpath to dstpatch in an atomic manner.

    It applies atomic directory copy by using the atomicity of overwriting a
    link (rename syscall).

    In case the remove_src flag argument is True, the srcpath is deleted.

    Note: In case of an interruption, it is assured that the destination is
    intact, pointing to the previous data or the new one. Intermediate
    temporary files  or the srcpath may still exists on the filesystem.
    """
    rand_suffix = random_iface_name(max_length=8)
    rand_dstpath = dstpath + '.' + rand_suffix
    rand_dstpath_symlink = rand_dstpath + '.ln'

    shutil.copytree(srcpath, rand_dstpath)
    os.symlink(rand_dstpath, rand_dstpath_symlink)

    old_realdstpath = os.path.realpath(dstpath)
    old_realdstpath_existed = old_realdstpath != dstpath

    _fsynctree(rand_dstpath)

    os.rename(rand_dstpath_symlink, dstpath)
    if old_realdstpath_existed:
        fileutils.rm_tree(old_realdstpath)
    if remove_src:
        fileutils.rm_tree(srcpath)
Ejemplo n.º 5
0
def _atomic_copytree(srcpath, dstpath, remove_src=False):
    """
    Copy srcpath to dstpatch in an atomic manner.

    It applies atomic directory copy by using the atomicity of overwriting a
    link (rename syscall).

    In case the remove_src flag argument is True, the srcpath is deleted.

    Note: In case of an interruption, it is assured that the destination is
    intact, pointing to the previous data or the new one. Intermediate
    temporary files  or the srcpath may still exists on the filesystem.
    """
    rand_suffix = random_iface_name(max_length=8)
    rand_dstpath = dstpath + '.' + rand_suffix
    rand_dstpath_symlink = rand_dstpath + '.ln'

    shutil.copytree(srcpath, rand_dstpath)
    os.symlink(rand_dstpath, rand_dstpath_symlink)

    old_realdstpath = os.path.realpath(dstpath)
    old_realdstpath_existed = old_realdstpath != dstpath

    _fsynctree(rand_dstpath)

    os.rename(rand_dstpath_symlink, dstpath)
    if old_realdstpath_existed:
        fileutils.rm_tree(old_realdstpath)
    if remove_src:
        fileutils.rm_tree(srcpath)
Ejemplo n.º 6
0
def bond_device(slaves, prefix='bond', max_length=11):
    check_sysfs_bond_permission()
    name = random_iface_name(prefix, max_length)
    with linkbond.Bond(name, slaves) as bond:
        bond.create()
        yield bond.master
    bond.destroy()
Ejemplo n.º 7
0
    def test_get_bonding_options(self):
        INTERVAL = '12345'
        bondName = random_iface_name()

        with open(BONDING_MASTERS, 'w') as bonds:
            bonds.write('+' + bondName)
            bonds.flush()

            try:  # no error is anticipated but let's make sure we can clean up
                self.assertEqual(
                    self._bond_opts_without_mode(bondName),
                    {},
                    'This test fails when a new bonding option is added to '
                    'the kernel. Please run vdsm-tool dump-bonding-options` '
                    'and retest.',
                )

                with open(bonding.BONDING_OPT % (bondName, 'miimon'),
                          'w') as opt:
                    opt.write(INTERVAL)

                self.assertEqual(
                    self._bond_opts_without_mode(bondName),
                    {'miimon': INTERVAL},
                )

            finally:
                bonds.write('-' + bondName)
Ejemplo n.º 8
0
 def test_bond_create_failure_on_slave_add(self, bond_with_slaves):
     bond_name = random_iface_name('bond_', max_length=11)
     with pytest.raises(IOError):
         with Bond(bond_name) as broken_bond:
             broken_bond.create()
             broken_bond.add_slaves(bond_with_slaves.slaves)
     assert not Bond(bond_name).exists()
Ejemplo n.º 9
0
def bond_device(prefix='bond_', max_length=11):
    bond_name = random_iface_name(prefix, max_length)
    bond = Bond(bond_name)
    bond.create()
    try:
        yield bond
    finally:
        bond.destroy()
Ejemplo n.º 10
0
def bond_device(prefix='bond_', max_length=11):
    bond_name = random_iface_name(prefix, max_length)
    bond = Bond(bond_name)
    bond.create()
    try:
        yield bond
    finally:
        bond.destroy()
Ejemplo n.º 11
0
def veth_pair(prefix='veth_', max_length=15):
    """
    Yield a pair of veth devices. This assumes root privileges (currently
    required by all tests anyway).

    Both sides of the pair have a pseudo-random suffix (e.g. veth_m6Lz7uMK9c).
    """
    left_side = random_iface_name(prefix, max_length)
    right_side = random_iface_name(prefix, max_length)
    try:
        linkAdd(left_side, linkType='veth', args=('peer', 'name', right_side))
    except IPRoute2Error as e:
        raise SkipTest('Failed to create a veth pair: %s', e)
    try:
        yield left_side, right_side
    finally:
        # the peer device is removed by the kernel
        linkDel(left_side)
Ejemplo n.º 12
0
def has_sysfs_bond_permission():
    BondSysFS = linkbond.sysfs_driver.BondSysFS
    bond = BondSysFS(random_iface_name('check_', max_length=11))
    try:
        bond.create()
        bond.destroy()
    except IOError:
        return False
    return True
Ejemplo n.º 13
0
def has_sysfs_bond_permission():
    BondSysFS = linkbond.sysfs_driver.BondSysFS
    bond = BondSysFS(random_iface_name('check_', max_length=11))
    try:
        bond.create()
        bond.destroy()
    except IOError:
        return False
    return True
Ejemplo n.º 14
0
def veth_pair(prefix='veth_', max_length=15):
    """
    Yield a pair of veth devices. This assumes root privileges (currently
    required by all tests anyway).

    Both sides of the pair have a pseudo-random suffix (e.g. veth_m6Lz7uMK9c).
    """
    left_side = random_iface_name(prefix, max_length)
    right_side = random_iface_name(prefix, max_length)
    try:
        linkAdd(left_side, linkType='veth',
                args=('peer', 'name', right_side))
    except IPRoute2Error as e:
        raise SkipTest('Failed to create a veth pair: %s', e)
    try:
        yield left_side, right_side
    finally:
        # the peer device is removed by the kernel
        linkDel(left_side)
Ejemplo n.º 15
0
    def test_bond_create_failure_on_slave_add(self):
        with dummy_devices(2) as (nic1, nic2):
            with bond_device() as base_bond:
                base_bond.add_slaves((nic1, nic2))

                bond_name = random_iface_name('bond_', max_length=11)
                with self.assertRaises(IOError):
                    with Bond(bond_name) as broken_bond:
                        broken_bond.create()
                        broken_bond.add_slaves((nic1, nic2))
                self.assertFalse(Bond(bond_name).exists())
Ejemplo n.º 16
0
    def test_bond_create_failure_on_slave_add(self):
        with dummy_devices(2) as (nic1, nic2):
            with bond_device() as base_bond:
                base_bond.add_slaves((nic1, nic2))

                bond_name = random_iface_name('bond_', max_length=11)
                with self.assertRaises(IOError):
                    with Bond(bond_name) as broken_bond:
                        broken_bond.create()
                        broken_bond.add_slaves((nic1, nic2))
                self.assertFalse(Bond(bond_name).exists())
Ejemplo n.º 17
0
def _get_bonding_options_name2numeric():
    """
    Return a map of options values per mode, in a dictionary of dictionaries.
    All keys are strings.
    """
    bond_name = random_iface_name()
    opts = {}
    for mode in range(_MAX_BONDING_MODES + 1):
        mode = str(mode)
        # The bond is created per mode to resolve an EBUSY error
        # that appears randomly when changing bond mode and modifying its
        # attributes. (Seen only on CI runs)
        with _bond_device(bond_name, mode):
            opts[mode] = _bond_opts_name2numeric_filtered(bond_name)

    return opts
Ejemplo n.º 18
0
def _get_bonding_options_name2numeric():
    """
    Return a map of options values per mode, in a dictionary of dictionaries.
    All keys are strings.
    """
    bond_name = random_iface_name('bondscan-')
    opts = {}
    for mode in range(_MAX_BONDING_MODES + 1):
        mode = str(mode)
        # The bond is created per mode to resolve an EBUSY error
        # that appears randomly when changing bond mode and modifying its
        # attributes. (Seen only on CI runs)
        with _bond_device(bond_name, mode):
            opts[mode] = _bond_opts_name2numeric_filtered(bond_name)

    return opts
Ejemplo n.º 19
0
    def save(self):
        self._clearDisk()
        rand_suffix = random_iface_name(max_length=8)
        rand_netconf_path = self.netconf_path + '.' + rand_suffix
        rand_nets_path = os.path.join(rand_netconf_path, NETCONF_NETS)
        rand_bonds_path = os.path.join(rand_netconf_path, NETCONF_BONDS)
        rand_devs_path = os.path.join(rand_netconf_path, NETCONF_DEVS)

        self._save_config(self.networks, rand_nets_path)
        self._save_config(self.bonds, rand_bonds_path)
        self._save_config(self.devices, rand_devs_path)

        _atomic_copytree(rand_netconf_path, self.netconf_path, remove_src=True)

        logging.info(
            'Saved new config %r to [%s,%s,%s]' %
            (self, self.networksPath, self.bondingsPath, self.devicesPath))
Ejemplo n.º 20
0
def _store_net_config():
    """
    Declare the current running config as 'safe' and persist this safe config.

    It is implemented by copying the running config to the persistent (safe)
    config in an atomic manner.
    It applies atomic directory copy by using the atomicity of overwriting a
    link (rename syscall).
    """
    safeconf_dir = CONF_PERSIST_DIR[:-1]
    rand_suffix = random_iface_name(max_length=8)
    new_safeconf_dir = safeconf_dir + '.' + rand_suffix
    new_safeconf_symlink = new_safeconf_dir + '.ln'

    shutil.copytree(CONF_RUN_DIR[:-1], new_safeconf_dir)
    os.symlink(new_safeconf_dir, new_safeconf_symlink)

    real_old_safeconf_dir = os.path.realpath(safeconf_dir)
    os.rename(new_safeconf_symlink, safeconf_dir)
    real_old_safeconf_dir_existed = real_old_safeconf_dir != safeconf_dir
    if real_old_safeconf_dir_existed:
        fileutils.rm_tree(real_old_safeconf_dir)
Ejemplo n.º 21
0
def _store_net_config():
    """
    Declare the current running config as 'safe' and persist this safe config.

    It is implemented by copying the running config to the persistent (safe)
    config in an atomic manner.
    It applies atomic directory copy by using the atomicity of overwriting a
    link (rename syscall).
    """
    safeconf_dir = CONF_PERSIST_DIR[:-1]
    rand_suffix = random_iface_name(max_length=8)
    new_safeconf_dir = safeconf_dir + '.' + rand_suffix
    new_safeconf_symlink = new_safeconf_dir + '.ln'

    shutil.copytree(CONF_RUN_DIR[:-1], new_safeconf_dir)
    os.symlink(new_safeconf_dir, new_safeconf_symlink)

    real_old_safeconf_dir = os.path.realpath(safeconf_dir)
    os.rename(new_safeconf_symlink, safeconf_dir)
    real_old_safeconf_dir_existed = real_old_safeconf_dir != safeconf_dir
    if real_old_safeconf_dir_existed:
        fileutils.rm_tree(real_old_safeconf_dir)
Ejemplo n.º 22
0
    def save(self):
        self._clearDisk()
        rand_suffix = random_iface_name(max_length=8)
        rand_netconf_path = self.netconf_path + '.' + rand_suffix
        rand_nets_path = os.path.join(rand_netconf_path, NETCONF_NETS)
        rand_bonds_path = os.path.join(rand_netconf_path, NETCONF_BONDS)
        rand_devs_path = os.path.join(rand_netconf_path, NETCONF_DEVS)

        self._save_config(self.networks, rand_nets_path)
        self._save_config(self.bonds, rand_bonds_path)
        self._save_config(self.devices, rand_devs_path)

        _atomic_copytree(
            rand_netconf_path, self.netconf_path, remove_src=True)

        logging.info(
            'Saved new config %r to [%s,%s,%s]' % (
                self,
                self.networksPath,
                self.bondingsPath,
                self.devicesPath
            )
        )
Ejemplo n.º 23
0
def _get_default_bonding_options():
    """
    Return default options per mode, in a dictionary of dictionaries. All keys
    are strings.
    """
    bond_name = random_iface_name()
    with _bond_device(bond_name):
        default_mode = sysfs_options.properties(bond_name, ('mode',))['mode']

    # read default values for all modes
    opts = {}
    for mode in range(_MAX_BONDING_MODES + 1):
        mode = str(mode)
        # The bond is created per mode to resolve an EBUSY error
        # that appears randomly when changing bond mode and modifying its
        # attributes. (Seen only on CI runs)
        with _bond_device(bond_name, mode):
            opts[mode] = sysfs_options.properties(
                bond_name,
                filter_out_properties=sysfs_options.EXCLUDED_BONDING_ENTRIES)
            opts[mode]['mode'] = default_mode

    return opts
Ejemplo n.º 24
0
def _get_default_bonding_options():
    """
    Return default options per mode, in a dictionary of dictionaries. All keys
    are strings.
    """
    bond_name = random_iface_name('bondscan-')
    with _bond_device(bond_name):
        default_mode = sysfs_options.properties(bond_name, ('mode',))['mode']

    # read default values for all modes
    opts = {}
    for mode in range(_MAX_BONDING_MODES + 1):
        mode = str(mode)
        # The bond is created per mode to resolve an EBUSY error
        # that appears randomly when changing bond mode and modifying its
        # attributes. (Seen only on CI runs)
        with _bond_device(bond_name, mode):
            opts[mode] = sysfs_options.properties(
                bond_name,
                filter_out_properties=sysfs_options.EXCLUDED_BONDING_ENTRIES)
            opts[mode]['mode'] = default_mode

    return opts
Ejemplo n.º 25
0
    def test_get_bonding_options(self):
        INTERVAL = '12345'
        bondName = random_iface_name()

        with open(BONDING_MASTERS, 'w') as bonds:
            bonds.write('+' + bondName)
            bonds.flush()

            try:  # no error is anticipated but let's make sure we can clean up
                self.assertEqual(
                    self._bond_opts_without_mode(bondName), {},
                    'This test fails when a new bonding option is added to '
                    'the kernel. Please run vdsm-tool dump-bonding-options` '
                    'and retest.')

                with open(bonding.BONDING_OPT % (bondName, 'miimon'),
                          'w') as opt:
                    opt.write(INTERVAL)

                self.assertEqual(self._bond_opts_without_mode(bondName),
                                 {'miimon': INTERVAL})

            finally:
                bonds.write('-' + bondName)
Ejemplo n.º 26
0
 def __init__(self, prefix='vdsm-', max_length=11):
     self.devName = random_iface_name(prefix, max_length)
Ejemplo n.º 27
0
 def _create_br_name():
     return random_iface_name(prefix=BRIDGE_PREFIX)
Ejemplo n.º 28
0
 def __init__(self, prefix='vdsm-', max_length=11):
     self.devName = random_iface_name(prefix, max_length)
Ejemplo n.º 29
0
def iface_name():
    return random_iface_name('bond', max_length=11, digit_only=True)
Ejemplo n.º 30
0
def iface_name():
    return random_iface_name('bond', max_length=11, digit_only=True)
Ejemplo n.º 31
0
def random_interface_name(iface_prefix):
    return random_iface_name(prefix=iface_prefix)
Ejemplo n.º 32
0
Archivo: switch.py Proyecto: EdDev/vdsm
 def _create_br_name():
     return random_iface_name(prefix=BRIDGE_PREFIX)