aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--etc/os-net-config/samples/ib_interface.json2
-rw-r--r--etc/os-net-config/samples/ib_interface.yaml2
-rw-r--r--etc/os-net-config/samples/interface.json8
-rw-r--r--etc/os-net-config/samples/interface.yaml7
-rw-r--r--os_net_config/cli.py2
-rw-r--r--os_net_config/impl_eni.py9
-rw-r--r--os_net_config/impl_ifcfg.py38
-rw-r--r--os_net_config/objects.py7
-rw-r--r--os_net_config/tests/test_impl_eni.py17
-rw-r--r--os_net_config/tests/test_impl_ifcfg.py14
-rw-r--r--os_net_config/tests/test_objects.py25
11 files changed, 101 insertions, 30 deletions
diff --git a/etc/os-net-config/samples/ib_interface.json b/etc/os-net-config/samples/ib_interface.json
index 4e42867..f552af3 100644
--- a/etc/os-net-config/samples/ib_interface.json
+++ b/etc/os-net-config/samples/ib_interface.json
@@ -20,7 +20,7 @@
"type": "ib_interface",
"name": "ib1",
"use_dhcp": true,
- "defroute": no
+ "defroute": false
}
]
}
diff --git a/etc/os-net-config/samples/ib_interface.yaml b/etc/os-net-config/samples/ib_interface.yaml
index f930471..6210f0a 100644
--- a/etc/os-net-config/samples/ib_interface.yaml
+++ b/etc/os-net-config/samples/ib_interface.yaml
@@ -15,4 +15,4 @@ network_config:
type: interface
name: ib1
use_dhcp: true
- defroute: no \ No newline at end of file
+ defroute: false
diff --git a/etc/os-net-config/samples/interface.json b/etc/os-net-config/samples/interface.json
index 6eb8f62..7b70e05 100644
--- a/etc/os-net-config/samples/interface.json
+++ b/etc/os-net-config/samples/interface.json
@@ -25,8 +25,14 @@
"type": "interface",
"name": "em2",
"use_dhcp": true,
- "defroute": no,
+ "defroute": false,
"ethtool_opts": "speed 1000 duplex full"
+ },
+ {
+ "type": "interface",
+ "name": "em3",
+ "use_dhcp": true,
+ "hotplug": true
}
]
}
diff --git a/etc/os-net-config/samples/interface.yaml b/etc/os-net-config/samples/interface.yaml
index 725091b..4c4269e 100644
--- a/etc/os-net-config/samples/interface.yaml
+++ b/etc/os-net-config/samples/interface.yaml
@@ -19,5 +19,10 @@ network_config:
type: interface
name: em2
use_dhcp: true
- defroute: no
+ defroute: false
ethtool_opts: "speed 1000 duplex full"
+ -
+ type: interface
+ name: em3
+ use_dhcp: true
+ hotplug: true
diff --git a/os_net_config/cli.py b/os_net_config/cli.py
index c0ac5c4..479b3a3 100644
--- a/os_net_config/cli.py
+++ b/os_net_config/cli.py
@@ -186,7 +186,7 @@ def main(argv=sys.argv):
files_changed = provider.apply(cleanup=opts.cleanup,
activate=not opts.no_activate)
if opts.noop:
- for location, data in files_changed.iteritems():
+ for location, data in files_changed.items():
print("File: %s\n" % location)
print(data)
print("----")
diff --git a/os_net_config/impl_eni.py b/os_net_config/impl_eni.py
index 5b91270..360d8c8 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:
@@ -212,12 +215,12 @@ class ENINetConfig(os_net_config.NetConfig):
# write out bridges first. This ensures that an ifup -a
# on reboot brings them up first
- for bridge_name, bridge_data in self.bridges.iteritems():
+ for bridge_name, bridge_data in self.bridges.items():
route_data = self.routes.get(bridge_name)
bridge_data += (route_data or '')
new_config += bridge_data
- for interface_name, iface_data in self.interfaces.iteritems():
+ for interface_name, iface_data in self.interfaces.items():
route_data = self.routes.get(interface_name)
iface_data += (route_data or '')
new_config += iface_data
diff --git a/os_net_config/impl_ifcfg.py b/os_net_config/impl_ifcfg.py
index 41d5f8c..6d3c681 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"
@@ -283,15 +286,18 @@ class IfcfgNetConfig(os_net_config.NetConfig):
data += "OVS_BRIDGE=%s\n" % base_opt.bridge_name
elif isinstance(base_opt, objects.OvsDpdkBond):
ovs_extra.extend(base_opt.ovs_extra)
- if base_opt.primary_interface_name:
- primary_name = base_opt.primary_interface_name
- self.bond_primary_ifaces[base_opt.name] = primary_name
+ # Referring to bug:1643026, the below commenting of the interfaces,
+ # is to workaround the error, but is not the long term solution.
+ # The long term solution is to run DPDK options before
+ # os-net-config, which is being tracked at BUG:1654975
+ # if base_opt.primary_interface_name:
+ # primary_name = base_opt.primary_interface_name
+ # self.bond_primary_ifaces[base_opt.name] = primary_name
data += "DEVICETYPE=ovs\n"
data += "TYPE=OVSDPDKBond\n"
data += "OVS_BRIDGE=%s\n" % base_opt.bridge_name
if base_opt.members:
members = [member.name for member in base_opt.members]
- self.member_names[base_opt.name] = members
data += ("BOND_IFACES=\"%s\"\n" % " ".join(members))
if base_opt.ovs_options:
data += "OVS_OPTIONS=\"%s\"\n" % base_opt.ovs_options
@@ -678,7 +684,7 @@ class IfcfgNetConfig(os_net_config.NetConfig):
nfvswitch_internal_ifaces = [] # nfvswitch internal/management ports
stop_dhclient_interfaces = []
- for interface_name, iface_data in self.interface_data.iteritems():
+ for interface_name, iface_data in self.interface_data.items():
route_data = self.route_data.get(interface_name, '')
route6_data = self.route6_data.get(interface_name, '')
interface_path = self.root_dir + ifcfg_config_path(interface_name)
@@ -706,7 +712,7 @@ class IfcfgNetConfig(os_net_config.NetConfig):
logger.info('No changes required for interface: %s' %
interface_name)
- for interface_name, iface_data in self.ivsinterface_data.iteritems():
+ for interface_name, iface_data in self.ivsinterface_data.items():
route_data = self.route_data.get(interface_name, '')
route6_data = self.route6_data.get(interface_name, '')
interface_path = self.root_dir + ifcfg_config_path(interface_name)
@@ -727,7 +733,7 @@ class IfcfgNetConfig(os_net_config.NetConfig):
logger.info('No changes required for ivs interface: %s' %
interface_name)
- for iface_name, iface_data in self.nfvswitch_intiface_data.iteritems():
+ for iface_name, iface_data in self.nfvswitch_intiface_data.items():
route_data = self.route_data.get(iface_name, '')
route6_data = self.route6_data.get(iface_name, '')
iface_path = self.root_dir + ifcfg_config_path(iface_name)
@@ -748,7 +754,7 @@ class IfcfgNetConfig(os_net_config.NetConfig):
logger.info('No changes required for nfvswitch interface: %s' %
iface_name)
- for vlan_name, vlan_data in self.vlan_data.iteritems():
+ for vlan_name, vlan_data in self.vlan_data.items():
route_data = self.route_data.get(vlan_name, '')
route6_data = self.route6_data.get(vlan_name, '')
vlan_path = self.root_dir + ifcfg_config_path(vlan_name)
@@ -768,7 +774,7 @@ class IfcfgNetConfig(os_net_config.NetConfig):
logger.info('No changes required for vlan interface: %s' %
vlan_name)
- for bridge_name, bridge_data in self.bridge_data.iteritems():
+ for bridge_name, bridge_data in self.bridge_data.items():
route_data = self.route_data.get(bridge_name, '')
route6_data = self.route6_data.get(bridge_name, '')
bridge_path = self.root_dir + bridge_config_path(bridge_name)
@@ -792,7 +798,7 @@ class IfcfgNetConfig(os_net_config.NetConfig):
else:
logger.info('No changes required for bridge: %s' % bridge_name)
- for bridge_name, bridge_data in self.linuxbridge_data.iteritems():
+ for bridge_name, bridge_data in self.linuxbridge_data.items():
route_data = self.route_data.get(bridge_name, '')
route6_data = self.route6_data.get(bridge_name, '')
bridge_path = self.root_dir + bridge_config_path(bridge_name)
@@ -812,7 +818,7 @@ class IfcfgNetConfig(os_net_config.NetConfig):
else:
logger.info('No changes required for bridge: %s' % bridge_name)
- for team_name, team_data in self.linuxteam_data.iteritems():
+ for team_name, team_data in self.linuxteam_data.items():
route_data = self.route_data.get(team_name, '')
route6_data = self.route6_data.get(team_name, '')
team_path = self.root_dir + bridge_config_path(team_name)
@@ -833,7 +839,7 @@ class IfcfgNetConfig(os_net_config.NetConfig):
logger.info('No changes required for linux team: %s' %
team_name)
- for bond_name, bond_data in self.linuxbond_data.iteritems():
+ for bond_name, bond_data in self.linuxbond_data.items():
route_data = self.route_data.get(bond_name, '')
route6_data = self.route6_data.get(bond_name, '')
bond_path = self.root_dir + bridge_config_path(bond_name)
@@ -855,7 +861,7 @@ class IfcfgNetConfig(os_net_config.NetConfig):
bond_name)
# Infiniband interfaces are handled similarly to Ethernet interfaces
- for interface_name, iface_data in self.ib_interface_data.iteritems():
+ for interface_name, iface_data in self.ib_interface_data.items():
route_data = self.route_data.get(interface_name, '')
route6_data = self.route6_data.get(interface_name, '')
interface_path = self.root_dir + ifcfg_config_path(interface_name)
@@ -906,10 +912,10 @@ class IfcfgNetConfig(os_net_config.NetConfig):
for bridge in restart_bridges:
self.ifdown(bridge, iftype='bridge')
- for oldname, newname in self.renamed_interfaces.iteritems():
+ for oldname, newname in self.renamed_interfaces.items():
self.ifrename(oldname, newname)
- for location, data in update_files.iteritems():
+ for location, data in update_files.items():
self.write_config(location, data)
if ivs_uplinks or ivs_interfaces:
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..54d153c 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))
@@ -407,7 +428,7 @@ class TestIvsInterface(base.TestCase):
objects.IvsBridge.from_json,
json.loads(data))
expected = 'IVS does not support bond interfaces.'
- self.assertIn(expected, err)
+ self.assertIn(expected, six.text_type(err))
class TestNfvswitchBridge(base.TestCase):
@@ -472,7 +493,7 @@ class TestNfvswitchInterface(base.TestCase):
objects.NfvswitchBridge.from_json,
json.loads(data))
expected = 'NFVSwitch does not support bond interfaces.'
- self.assertIn(expected, err)
+ self.assertIn(expected, six.text_type(err))
class TestBond(base.TestCase):