diff options
author | 2016-11-07 17:57:02 -0330 | |
---|---|---|
committer | 2016-11-18 14:38:45 -0330 | |
commit | 433a0f3cbe59fd5da183245bf7e6dcd4af4b8c88 (patch) | |
tree | a70bd0e53a3b73bb5c350982459b048d2dbc8c79 /os_net_config | |
parent | 9971eb3af988b1f7c003048af161489ab79b1b0c (diff) |
Add support for enabling hotplug on interfaces
This patch adds support for enabling hotplugging on interfaces (disabled
by default). This is useful for configuring SR-IOV root devices so that
they "return" to the system when no longer used by a VM.
Note: also updates an invalid value in the interface and ib_interface
sample files.
Partial-Bug: #1639901
Change-Id: Idfc17d6f20bb306271838895bc53f4b109dd664d
Diffstat (limited to 'os_net_config')
-rw-r--r-- | os_net_config/impl_eni.py | 5 | ||||
-rw-r--r-- | os_net_config/impl_ifcfg.py | 5 | ||||
-rw-r--r-- | os_net_config/objects.py | 7 | ||||
-rw-r--r-- | os_net_config/tests/test_impl_eni.py | 17 | ||||
-rw-r--r-- | os_net_config/tests/test_impl_ifcfg.py | 14 | ||||
-rw-r--r-- | os_net_config/tests/test_objects.py | 21 |
6 files changed, 63 insertions, 6 deletions
diff --git a/os_net_config/impl_eni.py b/os_net_config/impl_eni.py index 5b91270..c6252ce 100644 --- a/os_net_config/impl_eni.py +++ b/os_net_config/impl_eni.py @@ -127,7 +127,10 @@ class ENINetConfig(os_net_config.NetConfig): data += address_data data += " vlan-raw-device %s\n" % interface.device else: - data += "auto %s\n" % interface.name + if isinstance(interface, objects.Interface) and interface.hotplug: + data += "allow-hotplug %s\n" % interface.name + else: + data += "auto %s\n" % interface.name data += _iface data += address_data if interface.mtu: diff --git a/os_net_config/impl_ifcfg.py b/os_net_config/impl_ifcfg.py index 41d5f8c..bcfc4dc 100644 --- a/os_net_config/impl_ifcfg.py +++ b/os_net_config/impl_ifcfg.py @@ -131,7 +131,10 @@ class IfcfgNetConfig(os_net_config.NetConfig): data = "# This file is autogenerated by os-net-config\n" data += "DEVICE=%s\n" % base_opt.name data += "ONBOOT=yes\n" - data += "HOTPLUG=no\n" + if isinstance(base_opt, objects.Interface) and base_opt.hotplug: + data += "HOTPLUG=yes\n" + else: + data += "HOTPLUG=no\n" data += "NM_CONTROLLED=no\n" if not base_opt.dns_servers and not base_opt.use_dhcp: data += "PEERDNS=no\n" diff --git a/os_net_config/objects.py b/os_net_config/objects.py index 8d52e73..741f304 100644 --- a/os_net_config/objects.py +++ b/os_net_config/objects.py @@ -287,7 +287,7 @@ class Interface(_BaseOpts): def __init__(self, name, use_dhcp=False, use_dhcpv6=False, addresses=None, routes=None, mtu=None, primary=False, nic_mapping=None, persist_mapping=False, defroute=True, dhclient_args=None, - dns_servers=None, ethtool_opts=None): + dns_servers=None, ethtool_opts=None, hotplug=False): addresses = addresses or [] routes = routes or [] dns_servers = dns_servers or [] @@ -296,13 +296,16 @@ class Interface(_BaseOpts): persist_mapping, defroute, dhclient_args, dns_servers) self.ethtool_opts = ethtool_opts + self.hotplug = hotplug @staticmethod def from_json(json): name = _get_required_field(json, 'name', 'Interface') + hotplug = strutils.bool_from_string(str(json.get('hotplug', False))) opts = _BaseOpts.base_opts_from_json(json) ethtool_opts = json.get('ethtool_opts', None) - return Interface(name, *opts, ethtool_opts=ethtool_opts) + return Interface(name, *opts, ethtool_opts=ethtool_opts, + hotplug=hotplug) class Vlan(_BaseOpts): diff --git a/os_net_config/tests/test_impl_eni.py b/os_net_config/tests/test_impl_eni.py index e445ed4..4911cb9 100644 --- a/os_net_config/tests/test_impl_eni.py +++ b/os_net_config/tests/test_impl_eni.py @@ -32,6 +32,12 @@ _V4_IFACE_STATIC_IP = _AUTO + """iface eth0 inet static netmask 255.255.255.0 """ +_IFACE_HOTPLUG = """allow-hotplug eth0 +iface eth0 inet static + address 192.168.1.2 + netmask 255.255.255.0 +""" + _V4_IFACE_STATIC_IP_MULTIPLE = (_V4_IFACE_STATIC_IP + _AUTO + """iface eth0 inet static address 10.0.0.2 @@ -117,8 +123,9 @@ class TestENINetConfig(base.TestCase): def get_route_config(self): return self.provider.routes[self.if_name] - def _default_interface(self, addr=[], rts=[]): - return objects.Interface(self.if_name, addresses=addr, routes=rts) + def _default_interface(self, addr=[], rts=[], hotplug=False): + return objects.Interface(self.if_name, addresses=addr, routes=rts, + hotplug=hotplug) def test_interface_no_ip(self): interface = self._default_interface() @@ -131,6 +138,12 @@ class TestENINetConfig(base.TestCase): self.provider.add_interface(interface) self.assertEqual(_V4_IFACE_STATIC_IP, self.get_interface_config()) + def test_add_interface_with_hotplug(self): + v4_addr = objects.Address('192.168.1.2/24') + interface = self._default_interface(addr=[v4_addr], hotplug=True) + self.provider.add_interface(interface) + self.assertEqual(_IFACE_HOTPLUG, self.get_interface_config()) + def test_add_interface_with_v4_multiple(self): v4_addresses = [objects.Address('192.168.1.2/24'), objects.Address('10.0.0.2/8')] diff --git a/os_net_config/tests/test_impl_ifcfg.py b/os_net_config/tests/test_impl_ifcfg.py index 3a5a7db..9621b8c 100644 --- a/os_net_config/tests/test_impl_ifcfg.py +++ b/os_net_config/tests/test_impl_ifcfg.py @@ -33,6 +33,15 @@ NM_CONTROLLED=no PEERDNS=no """ +_HOTPLUG = """# This file is autogenerated by os-net-config +DEVICE=em1 +ONBOOT=yes +HOTPLUG=yes +NM_CONTROLLED=no +PEERDNS=no +BOOTPROTO=none +""" + _NO_IP = _BASE_IFCFG + "BOOTPROTO=none\n" _V4_IFCFG = _BASE_IFCFG + """BOOTPROTO=static @@ -386,6 +395,11 @@ class TestIfcfgNetConfig(base.TestCase): self.provider.add_interface(interface) self.assertEqual(_NO_IP, self.get_interface_config()) + def test_add_interface_with_hotplug(self): + interface = objects.Interface('em1', hotplug=True) + self.provider.add_interface(interface) + self.assertEqual(_HOTPLUG, self.get_interface_config()) + def test_add_base_interface_vlan(self): interface = objects.Interface('em1.120') self.provider.add_interface(interface) diff --git a/os_net_config/tests/test_objects.py b/os_net_config/tests/test_objects.py index ca2dd47..23a3bbe 100644 --- a/os_net_config/tests/test_objects.py +++ b/os_net_config/tests/test_objects.py @@ -98,6 +98,27 @@ class TestInterface(base.TestCase): self.assertEqual("em1", interface.name) self.assertTrue(interface.use_dhcp) + def test_from_json_hotplug(self): + data = """{ +"type": "interface", +"name": "em1", +"hotplug": true +} +""" + interface = objects.object_from_json(json.loads(data)) + self.assertEqual("em1", interface.name) + self.assertTrue(interface.hotplug) + + def test_from_json_hotplug_off_by_default(self): + data = """{ +"type": "interface", +"name": "em1" +} +""" + interface = objects.object_from_json(json.loads(data)) + self.assertEqual("em1", interface.name) + self.assertFalse(interface.hotplug) + def test_from_json_defroute(self): data = '{"type": "interface", "name": "em1", "use_dhcp": true}' interface1 = objects.object_from_json(json.loads(data)) |