diff --git a/nova/network/linux_net.py b/nova/network/linux_net.py index afa0d9cef7..6fbef8cb9b 100644 --- a/nova/network/linux_net.py +++ b/nova/network/linux_net.py @@ -1317,10 +1317,8 @@ class LinuxBridgeInterfaceDriver(LinuxNetInterfaceDriver): interface = 'vlan%s' % vlan_num if not nova.privsep.linux_net.device_exists(interface): LOG.debug('Starting VLAN interface %s', interface) - _execute('ip', 'link', 'add', 'link', bridge_interface, - 'name', interface, 'type', 'vlan', - 'id', vlan_num, run_as_root=True, - check_exit_code=[0, 2, 254]) + nova.privsep.linux_net.add_vlan(bridge_interface, interface, + vlan_num) # (danwent) the bridge will inherit this address, so we want to # make sure it is the value set from the NetworkManager if mac_address: diff --git a/nova/privsep/linux_net.py b/nova/privsep/linux_net.py index a57f122912..e78aefb65b 100644 --- a/nova/privsep/linux_net.py +++ b/nova/privsep/linux_net.py @@ -259,3 +259,10 @@ def modify_ebtables(table, rule, insert_rule=True): cmd.extend(rule) processutils.execute(*cmd, check_exit_code=[0]) + + +@nova.privsep.sys_admin_pctxt.entrypoint +def add_vlan(bridge_interface, interface, vlan_num): + processutils.execute('ip', 'link', 'add', 'link', bridge_interface, + 'name', interface, 'type', 'vlan', + 'id', vlan_num, check_exit_code=[0, 2, 254]) diff --git a/nova/tests/functional/api_sample_tests/api_sample_base.py b/nova/tests/functional/api_sample_tests/api_sample_base.py index 50852d7b28..737f0e2717 100644 --- a/nova/tests/functional/api_sample_tests/api_sample_base.py +++ b/nova/tests/functional/api_sample_tests/api_sample_base.py @@ -143,6 +143,7 @@ class ApiSampleTestBaseV21(testscenarios.WithScenarios, fake_true) self.stub_out('nova.privsep.linux_net._enable_ipv4_forwarding_inner', fake_noop) + self.stub_out('nova.privsep.linux_net.add_vlan', fake_noop) if self.availability_zones: self.useFixture( diff --git a/nova/tests/unit/network/test_linux_net.py b/nova/tests/unit/network/test_linux_net.py index 01e198ab13..6ce993f4fb 100644 --- a/nova/tests/unit/network/test_linux_net.py +++ b/nova/tests/unit/network/test_linux_net.py @@ -1300,25 +1300,20 @@ class LinuxNetworkTestCase(test.NoDBTestCase): mock_disabled.assert_called_once_with('fake-bridge') mock_delete.assert_called_once_with('fake-bridge') - @mock.patch.object(linux_net, '_execute') @mock.patch('nova.privsep.linux_net.device_exists', return_value=False) @mock.patch('nova.privsep.linux_net.set_device_mtu') @mock.patch('nova.privsep.linux_net.set_device_enabled') @mock.patch('nova.privsep.linux_net.set_device_macaddr') - def test_ensure_vlan(self, mock_set_macaddr, mock_set_enabled, - mock_set_device_mtu, mock_device_exists, - mock_execute): + @mock.patch('nova.privsep.linux_net.add_vlan') + def test_ensure_vlan(self, mock_add_vlan, mock_set_macaddr, + mock_set_enabled, mock_set_device_mtu, + mock_device_exists): interface = linux_net.LinuxBridgeInterfaceDriver.ensure_vlan( 1, 'eth0', 'MAC', 'MTU', "vlan_name") self.assertEqual("vlan_name", interface) mock_device_exists.assert_called_once_with('vlan_name') - expected_execute_args = [ - mock.call('ip', 'link', 'add', 'link', 'eth0', 'name', 'vlan_name', - 'type', 'vlan', 'id', 1, check_exit_code=[0, 2, 254], - run_as_root=True) - ] - self.assertEqual(expected_execute_args, mock_execute.mock_calls) + mock_add_vlan.assert_called_once_with('eth0', 'vlan_name', 1) mock_set_device_mtu.assert_called_once_with('vlan_name', 'MTU') mock_set_enabled.assert_called_once_with('vlan_name') mock_set_macaddr.assert_called_once_with('vlan_name', 'MAC') diff --git a/nova/tests/unit/network/test_manager.py b/nova/tests/unit/network/test_manager.py index dd97b1f64b..fdf8753319 100644 --- a/nova/tests/unit/network/test_manager.py +++ b/nova/tests/unit/network/test_manager.py @@ -2894,7 +2894,9 @@ class AllocateTestCase(test.TestCase): return_value=False) @mock.patch('nova.privsep.linux_net._enable_ipv4_forwarding_inner') @mock.patch('nova.privsep.linux_net.modify_ebtables') - def test_allocate_for_instance(self, mock_modify_ebtables, + @mock.patch('nova.privsep.linux_net.add_vlan') + def test_allocate_for_instance(self, mock_add_vlan, + mock_modify_ebtables, mock_forwarding_enable, mock_forwarding_check, mock_clean_conntrack, @@ -2977,7 +2979,9 @@ class AllocateTestCase(test.TestCase): @mock.patch('nova.privsep.linux_net.ipv4_forwarding_check', return_value=False) @mock.patch('nova.privsep.linux_net._enable_ipv4_forwarding_inner') - def test_allocate_for_instance_with_mac(self, mock_forwarding_enable, + @mock.patch('nova.privsep.linux_net.add_vlan') + def test_allocate_for_instance_with_mac(self, mock_add_vlan, + mock_forwarding_enable, mock_forwarding_check, mock_address_command, mock_change_ip, diff --git a/nova/tests/unit/privsep/test_linux_net.py b/nova/tests/unit/privsep/test_linux_net.py index 94a56ab43b..5b3f469512 100644 --- a/nova/tests/unit/privsep/test_linux_net.py +++ b/nova/tests/unit/privsep/test_linux_net.py @@ -152,3 +152,10 @@ class LinuxNetTestCase(test.NoDBTestCase): cmd = ['ebtables', '--concurrent', '-t', table] + ['-D'] + rule mock_execute.assert_called_once_with(*cmd, check_exit_code=[0]) + + @mock.patch('oslo_concurrency.processutils.execute') + def test_add_vlan(self, mock_execute): + nova.privsep.linux_net.add_vlan('eth0', 'vlan_name', 1) + cmd = ['ip', 'link', 'add', 'link', 'eth0', 'name', 'vlan_name', + 'type', 'vlan', 'id', 1] + mock_execute.assert_called_once_with(*cmd, check_exit_code=[0, 2, 254]) diff --git a/nova/tests/unit/virt/xenapi/test_xenapi.py b/nova/tests/unit/virt/xenapi/test_xenapi.py index f7a2ae602e..176d64d73d 100644 --- a/nova/tests/unit/virt/xenapi/test_xenapi.py +++ b/nova/tests/unit/virt/xenapi/test_xenapi.py @@ -1144,7 +1144,8 @@ class XenAPIVMTestCase(stubs.XenAPITestBase, @mock.patch('nova.privsep.linux_net.ipv4_forwarding_check', return_value=False) @mock.patch('nova.privsep.linux_net._enable_ipv4_forwarding_inner') - def test_spawn_vlanmanager(self, mock_forwarding_enable, + @mock.patch('nova.privsep.linux_net.add_vlan') + def test_spawn_vlanmanager(self, mock_add_vlan, mock_forwarding_enable, mock_forwarding_check, mock_address_command_horrid, mock_change_ip, mock_set_macaddr,