예제 #1
0
 def test_get_devicelist_raise_oserror(self):
     """get_devicelist raise any non-ENOENT OSerror."""
     error = OSError('Can not do it')
     error.errno = errno.EPERM  # Set non-ENOENT
     self.m_sys_path.side_effect = error
     with self.assertRaises(OSError) as context_manager:
         net.get_devicelist()
     exception = context_manager.exception
     self.assertEqual('Can not do it', str(exception))
예제 #2
0
 def test_get_devicelist_raise_oserror(self):
     """get_devicelist raise any non-ENOENT OSerror."""
     error = OSError('Can not do it')
     error.errno = errno.EPERM  # Set non-ENOENT
     self.m_sys_path.side_effect = error
     with self.assertRaises(OSError) as context_manager:
         net.get_devicelist()
     exception = context_manager.exception
     self.assertEqual('Can not do it', str(exception))
예제 #3
0
def maybe_perform_dhcp_discovery(nic=None):
    """Perform dhcp discovery if nic valid and dhclient command exists.

    If the nic is invalid or undiscoverable or dhclient command is not found,
    skip dhcp_discovery and return an empty dict.

    @param nic: Name of the network interface we want to run dhclient on.
    @return: A list of dicts representing dhcp options for each lease obtained
        from the dhclient discovery if run, otherwise an empty list is
        returned.
    """
    if nic is None:
        nic = find_fallback_nic()
        if nic is None:
            LOG.debug('Skip dhcp_discovery: Unable to find fallback nic.')
            return []
    elif nic not in get_devicelist():
        LOG.debug(
            'Skip dhcp_discovery: nic %s not found in get_devicelist.', nic)
        return []
    dhclient_path = util.which('dhclient')
    if not dhclient_path:
        LOG.debug('Skip dhclient configuration: No dhclient command found.')
        return []
    with temp_utils.tempdir(rmtree_ignore_errors=True,
                            prefix='cloud-init-dhcp-',
                            needs_exe=True) as tdir:
        # Use /var/tmp because /run/cloud-init/tmp is mounted noexec
        return dhcp_discovery(dhclient_path, nic, tdir)
예제 #4
0
파일: dhcp.py 프로젝트: vad1m/cloud-init
def maybe_perform_dhcp_discovery(nic=None):
    """Perform dhcp discovery if nic valid and dhclient command exists.

    If the nic is invalid or undiscoverable or dhclient command is not found,
    skip dhcp_discovery and return an empty dict.

    @param nic: Name of the network interface we want to run dhclient on.
    @return: A dict of dhcp options from the dhclient discovery if run,
        otherwise an empty dict is returned.
    """
    if nic is None:
        nic = find_fallback_nic()
        if nic is None:
            LOG.debug('Skip dhcp_discovery: Unable to find fallback nic.')
            return {}
    elif nic not in get_devicelist():
        LOG.debug('Skip dhcp_discovery: nic %s not found in get_devicelist.',
                  nic)
        return {}
    dhclient_path = util.which('dhclient')
    if not dhclient_path:
        LOG.debug('Skip dhclient configuration: No dhclient command found.')
        return {}
    with util.tempdir(prefix='cloud-init-dhcp-') as tmpdir:
        return dhcp_discovery(dhclient_path, nic, tmpdir)
예제 #5
0
def maybe_perform_dhcp_discovery(nic=None):
    """Perform dhcp discovery if nic valid and dhclient command exists.

    If the nic is invalid or undiscoverable or dhclient command is not found,
    skip dhcp_discovery and return an empty dict.

    @param nic: Name of the network interface we want to run dhclient on.
    @return: A list of dicts representing dhcp options for each lease obtained
        from the dhclient discovery if run, otherwise an empty list is
        returned.
    """
    if nic is None:
        nic = find_fallback_nic()
        if nic is None:
            LOG.debug('Skip dhcp_discovery: Unable to find fallback nic.')
            return []
    elif nic not in get_devicelist():
        LOG.debug(
            'Skip dhcp_discovery: nic %s not found in get_devicelist.', nic)
        return []
    dhclient_path = util.which('dhclient')
    if not dhclient_path:
        LOG.debug('Skip dhclient configuration: No dhclient command found.')
        return []
    with temp_utils.tempdir(rmtree_ignore_errors=True,
                            prefix='cloud-init-dhcp-',
                            needs_exe=True) as tdir:
        # Use /var/tmp because /run/cloud-init/tmp is mounted noexec
        return dhcp_discovery(dhclient_path, nic, tdir)
예제 #6
0
def maybe_perform_dhcp_discovery(nic=None, dhcp_log_func=None):
    """Perform dhcp discovery if nic valid and dhclient command exists.

    If the nic is invalid or undiscoverable or dhclient command is not found,
    skip dhcp_discovery and return an empty dict.

    @param nic: Name of the network interface we want to run dhclient on.
    @param dhcp_log_func: A callable accepting the dhclient output and error
        streams.
    @return: A list of dicts representing dhcp options for each lease obtained
        from the dhclient discovery if run, otherwise an empty list is
        returned.
    """
    if nic is None:
        nic = find_fallback_nic()
        if nic is None:
            LOG.debug("Skip dhcp_discovery: Unable to find fallback nic.")
            raise NoDHCPLeaseInterfaceError()
    elif nic not in get_devicelist():
        LOG.debug("Skip dhcp_discovery: nic %s not found in get_devicelist.",
                  nic)
        raise NoDHCPLeaseInterfaceError()
    dhclient_path = subp.which("dhclient")
    if not dhclient_path:
        LOG.debug("Skip dhclient configuration: No dhclient command found.")
        raise NoDHCPLeaseMissingDhclientError()
    with temp_utils.tempdir(rmtree_ignore_errors=True,
                            prefix="cloud-init-dhcp-",
                            needs_exe=True) as tdir:
        # Use /var/tmp because /run/cloud-init/tmp is mounted noexec
        return dhcp_discovery(dhclient_path, nic, tdir, dhcp_log_func)
def get_link_local_nic(distro):
    nics = [
        f for f in cloudnet.get_devicelist()
        if distro.networking.is_physical(f)
    ]
    if not nics:
        return None
    return min(nics, key=lambda d: cloudnet.read_sys_net_int(d, "ifindex"))
예제 #8
0
 def _net_setup_link(self, run=False):
     """To ensure device link properties are applied, we poke
        udev to re-evaluate networkd .link files and call
        the setup_link udev builtin command
     """
     if not run:
         LOG.debug("netplan net_setup_link postcmd disabled")
         return
     setup_lnk = ['udevadm', 'test-builtin', 'net_setup_link']
     for cmd in [setup_lnk + [SYS_CLASS_NET + iface]
                 for iface in get_devicelist() if
                 os.path.islink(SYS_CLASS_NET + iface)]:
         util.subp(cmd, capture=True)
예제 #9
0
 def _net_setup_link(self, run=False):
     """To ensure device link properties are applied, we poke
        udev to re-evaluate networkd .link files and call
        the setup_link udev builtin command
     """
     if not run:
         LOG.debug("netplan net_setup_link postcmd disabled")
         return
     setup_lnk = ['udevadm', 'test-builtin', 'net_setup_link']
     for cmd in [setup_lnk + [SYS_CLASS_NET + iface]
                 for iface in get_devicelist() if
                 os.path.islink(SYS_CLASS_NET + iface)]:
         util.subp(cmd, capture=True)
예제 #10
0
    def network_config(self):
        """Generate a network config like net.generate_fallback_network() with
           the following execptions.

           1. Probe the drivers of the net-devices present and inject them in
              the network configuration under params: driver: <driver> value
           2. If the driver value is 'mlx4_core', the control mode should be
              set to manual.  The device will be later used to build a bond,
              for now we want to ensure the device gets named but does not
              break any network configuration
        """
        blacklist = ['mlx4_core']
        if not self._network_config:
            LOG.debug('Azure: generating fallback configuration')
            # generate a network config, blacklist picking any mlx4_core devs
            netconfig = net.generate_fallback_config(
                blacklist_drivers=blacklist, config_driver=True)

            # if we have any blacklisted devices, update the network_config to
            # include the device, mac, and driver values, but with no ip
            # config; this ensures udev rules are generated but won't affect
            # ip configuration
            bl_found = 0
            for bl_dev in [
                    dev for dev in net.get_devicelist()
                    if net.device_driver(dev) in blacklist
            ]:
                bl_found += 1
                cfg = {
                    'type': 'physical',
                    'name': 'vf%d' % bl_found,
                    'mac_address': net.get_interface_mac(bl_dev),
                    'params': {
                        'driver': net.device_driver(bl_dev),
                        'device_id': net.device_devid(bl_dev),
                    },
                }
                netconfig['config'].append(cfg)

            self._network_config = netconfig

        return self._network_config
예제 #11
0
def assign_ipv4_link_local(nic=None):
    """Bring up NIC using an address using link-local (ip4LL) IPs. On
       DigitalOcean, the link-local domain is per-droplet routed, so there
       is no risk of collisions. However, to be more safe, the ip4LL
       address is random.
    """

    if not nic:
        for cdev in sorted(cloudnet.get_devicelist()):
            if cloudnet.is_physical(cdev):
                nic = cdev
                LOG.debug("assigned nic '%s' for link-local discovery", nic)
                break

    if not nic:
        raise RuntimeError("unable to find interfaces to access the"
                           "meta-data server. This droplet is broken.")

    addr = "169.254.{0}.{1}/16".format(random.randint(1, 168),
                                       random.randint(0, 255))

    ip_addr_cmd = ['ip', 'addr', 'add', addr, 'dev', nic]
    ip_link_cmd = ['ip', 'link', 'set', 'dev', nic, 'up']

    if not util.which('ip'):
        raise RuntimeError("No 'ip' command available to configure ip4LL "
                           "address")

    try:
        (result, _err) = util.subp(ip_addr_cmd)
        LOG.debug("assigned ip4LL address '%s' to '%s'", addr, nic)

        (result, _err) = util.subp(ip_link_cmd)
        LOG.debug("brought device '%s' up", nic)
    except Exception:
        util.logexc(
            LOG, "ip4LL address assignment of '%s' to '%s' failed."
            " Droplet networking will be broken", addr, nic)
        raise

    return nic
예제 #12
0
def assign_ipv4_link_local(nic=None):
    """Bring up NIC using an address using link-local (ip4LL) IPs. On
       DigitalOcean, the link-local domain is per-droplet routed, so there
       is no risk of collisions. However, to be more safe, the ip4LL
       address is random.
    """

    if not nic:
        for cdev in sorted(cloudnet.get_devicelist()):
            if cloudnet.is_physical(cdev):
                nic = cdev
                LOG.debug("assigned nic '%s' for link-local discovery", nic)
                break

    if not nic:
        raise RuntimeError("unable to find interfaces to access the"
                           "meta-data server. This droplet is broken.")

    addr = "169.254.{0}.{1}/16".format(random.randint(1, 168),
                                       random.randint(0, 255))

    ip_addr_cmd = ['ip', 'addr', 'add', addr, 'dev', nic]
    ip_link_cmd = ['ip', 'link', 'set', 'dev', nic, 'up']

    if not util.which('ip'):
        raise RuntimeError("No 'ip' command available to configure ip4LL "
                           "address")

    try:
        (result, _err) = util.subp(ip_addr_cmd)
        LOG.debug("assigned ip4LL address '%s' to '%s'", addr, nic)

        (result, _err) = util.subp(ip_link_cmd)
        LOG.debug("brought device '%s' up", nic)
    except Exception:
        util.logexc(LOG, "ip4LL address assignment of '%s' to '%s' failed."
                         " Droplet networking will be broken", addr, nic)
        raise

    return nic
예제 #13
0
def get_first_physical_interface():
    devs = [f for f in cloudnet.get_devicelist() if cloudnet.is_physical(f)]
    if not devs:
        raise RuntimeError("No interfaces find to configure link-local address")
    return min(devs, key=lambda d: cloudnet.read_sys_net_int(d, 'ifindex'))
예제 #14
0
 def test_get_devicelist_lists_any_subdirectories_in_sys_net(self):
     """get_devicelist returns a directory listing for SYS_CLASS_NET."""
     write_file(os.path.join(self.sysdir, 'eth0', 'operstate'), 'up')
     write_file(os.path.join(self.sysdir, 'eth1', 'operstate'), 'up')
     self.assertItemsEqual(['eth0', 'eth1'], net.get_devicelist())
예제 #15
0
 def test_get_devicelist_empty_with_no_devices_in_sys_net(self):
     """get_devicelist returns empty directoty listing for SYS_CLASS_NET."""
     self.assertEqual([], net.get_devicelist())
예제 #16
0
 def test_get_devicelist_empty_without_sys_net(self):
     """get_devicelist returns empty list when missing SYS_CLASS_NET."""
     self.m_sys_path.return_value = 'idontexist'
     self.assertEqual([], net.get_devicelist())
예제 #17
0
def get_link_local_nic():
    nics = [f for f in cloudnet.get_devicelist() if cloudnet.is_physical(f)]
    if not nics:
        return None
    return min(nics, key=lambda d: cloudnet.read_sys_net_int(d, 'ifindex'))
예제 #18
0
 def test_get_devicelist_empty_without_sys_net(self):
     """get_devicelist returns empty list when missing SYS_CLASS_NET."""
     self.m_sys_path.return_value = 'idontexist'
     self.assertEqual([], net.get_devicelist())
예제 #19
0
 def test_get_devicelist_empty_with_no_devices_in_sys_net(self):
     """get_devicelist returns empty directoty listing for SYS_CLASS_NET."""
     self.assertEqual([], net.get_devicelist())
예제 #20
0
 def get_devicelist(self) -> list:
     return net.get_devicelist()
예제 #21
0
def get_link_local_nic():
    nics = [f for f in cloudnet.get_devicelist() if cloudnet.is_physical(f)]
    if not nics:
        return None
    return min(nics, key=lambda d: cloudnet.read_sys_net_int(d, 'ifindex'))
예제 #22
0
 def test_get_devicelist_lists_any_subdirectories_in_sys_net(self):
     """get_devicelist returns a directory listing for SYS_CLASS_NET."""
     write_file(os.path.join(self.sysdir, 'eth0', 'operstate'), 'up')
     write_file(os.path.join(self.sysdir, 'eth1', 'operstate'), 'up')
     self.assertItemsEqual(['eth0', 'eth1'], net.get_devicelist())