diff --git a/os_vif/internal/ip/api.py b/os_vif/internal/ip/api.py index ea2aef6d..d1c32173 100644 --- a/os_vif/internal/ip/api.py +++ b/os_vif/internal/ip/api.py @@ -10,21 +10,10 @@ # License for the specific language governing permissions and limitations # under the License. -import os -import warnings - from oslo_log import log as logging -if os.name == 'nt': - warnings.warn('Support for Windows OS is deprecated.', - category=DeprecationWarning) - from os_vif.internal.ip.windows.impl_netifaces import \ - Netifaces as ip_lib_class -else: - from os_vif.internal.ip.linux.impl_pyroute2 import \ - PyRoute2 as ip_lib_class - +from os_vif.internal.ip.linux.impl_pyroute2 import PyRoute2 LOG = logging.getLogger(__name__) -ip = ip_lib_class() +ip = PyRoute2() diff --git a/os_vif/internal/ip/windows/__init__.py b/os_vif/internal/ip/windows/__init__.py deleted file mode 100644 index e69de29b..00000000 diff --git a/os_vif/internal/ip/windows/impl_netifaces.py b/os_vif/internal/ip/windows/impl_netifaces.py deleted file mode 100644 index 69424adb..00000000 --- a/os_vif/internal/ip/windows/impl_netifaces.py +++ /dev/null @@ -1,47 +0,0 @@ -# Derived from: neutron/agent/windows/ip_lib.py -# -# Licensed under the Apache License, Version 2.0 (the "License"); you may -# not use this file except in compliance with the License. You may obtain -# a copy of the License at -# -# http://www.apache.org/licenses/LICENSE-2.0 -# -# Unless required by applicable law or agreed to in writing, software -# distributed under the License is distributed on an "AS IS" BASIS, WITHOUT -# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the -# License for the specific language governing permissions and limitations -# under the License. - -import netifaces - -from oslo_log import log as logging - -from os_vif import exception -from os_vif.internal.ip import ip_command - -LOG = logging.getLogger(__name__) - - -class Netifaces(ip_command.IpCommand): - - def exists(self, device): - """Return True if the device exists in the namespace.""" - try: - return bool(netifaces.ifaddresses(device)) - except ValueError: - LOG.warning("The device does not exist on the system: %s", device) - return False - except OSError: - LOG.error("Failed to get interface addresses: %s", device) - return False - - def set(self, device, check_exit_code=None, state=None, mtu=None, - address=None, promisc=None, master=None): - exception.NotImplementedForOS(function='ip.set', os='Windows') - - def add(self, device, dev_type, check_exit_code=None, peer=None, link=None, - vlan_id=None): - exception.NotImplementedForOS(function='ip.add', os='Windows') - - def delete(self, device, check_exit_code=None): - exception.NotImplementedForOS(function='ip.delete', os='Windows') diff --git a/os_vif/tests/unit/internal/ip/test_api.py b/os_vif/tests/unit/internal/ip/test_api.py index 6bc43350..da3be7a7 100644 --- a/os_vif/tests/unit/internal/ip/test_api.py +++ b/os_vif/tests/unit/internal/ip/test_api.py @@ -10,30 +10,12 @@ # License for the specific language governing permissions and limitations # under the License. -import importlib - -from unittest import mock - from os_vif.internal.ip import api +from os_vif.internal.ip.linux import impl_pyroute2 from os_vif.tests.unit import base class TestIpApi(base.TestCase): - @staticmethod - def _reload_original_os_module(): - importlib.reload(api) - - def test_get_impl_windows(self): - self.addCleanup(self._reload_original_os_module) - with mock.patch('os.name', 'nt'): - importlib.reload(api) - from os_vif.internal.ip.windows import impl_netifaces - self.assertIsInstance(api.ip, impl_netifaces.Netifaces) - - def test_get_impl_linux(self): - self.addCleanup(self._reload_original_os_module) - with mock.patch('os.name', 'posix'): - importlib.reload(api) - from os_vif.internal.ip.linux import impl_pyroute2 - self.assertIsInstance(api.ip, impl_pyroute2.PyRoute2) + def test_get_impl(self): + self.assertIsInstance(api.ip, impl_pyroute2.PyRoute2) diff --git a/os_vif/tests/unit/internal/ip/windows/__init__.py b/os_vif/tests/unit/internal/ip/windows/__init__.py deleted file mode 100644 index e69de29b..00000000 diff --git a/os_vif/tests/unit/internal/ip/windows/test_impl_netifaces.py b/os_vif/tests/unit/internal/ip/windows/test_impl_netifaces.py deleted file mode 100644 index fc88149c..00000000 --- a/os_vif/tests/unit/internal/ip/windows/test_impl_netifaces.py +++ /dev/null @@ -1,46 +0,0 @@ -# Licensed under the Apache License, Version 2.0 (the "License"); you may -# not use this file except in compliance with the License. You may obtain -# a copy of the License at -# -# http://www.apache.org/licenses/LICENSE-2.0 -# -# Unless required by applicable law or agreed to in writing, software -# distributed under the License is distributed on an "AS IS" BASIS, WITHOUT -# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the -# License for the specific language governing permissions and limitations -# under the License. - -from unittest import mock - -import netifaces - -from os_vif.internal.ip.windows import impl_netifaces as ip_lib -from os_vif.tests.unit import base - - -class TestIPDevice(base.TestCase): - - def setUp(self): - super(TestIPDevice, self).setUp() - self.device_name = 'test_device' - self.mock_log = mock.patch.object(ip_lib, "LOG").start() - self.ip_lib = ip_lib.Netifaces() - - @mock.patch.object(netifaces, 'ifaddresses', return_value=True) - def test_exists(self, mock_ifaddresses): - self.assertTrue(self.ip_lib.exists(self.device_name)) - mock_ifaddresses.assert_called_once_with(self.device_name) - - @mock.patch.object(netifaces, 'ifaddresses', side_effect=ValueError()) - def test_exists_not_found(self, mock_ifaddresses): - self.assertFalse(self.ip_lib.exists(self.device_name)) - mock_ifaddresses.assert_called_once_with(self.device_name) - self.mock_log.warning.assert_called_once_with( - "The device does not exist on the system: %s", self.device_name) - - @mock.patch.object(netifaces, 'ifaddresses', side_effect=OSError()) - def test_exists_os_error_exception(self, mock_ifaddresses): - self.assertFalse(self.ip_lib.exists(self.device_name)) - mock_ifaddresses.assert_called_once_with(self.device_name) - self.mock_log.error.assert_called_once_with( - "Failed to get interface addresses: %s", self.device_name) diff --git a/releasenotes/notes/remove-windows-23df1c587d505d72.yaml b/releasenotes/notes/remove-windows-23df1c587d505d72.yaml new file mode 100644 index 00000000..4e628a12 --- /dev/null +++ b/releasenotes/notes/remove-windows-23df1c587d505d72.yaml @@ -0,0 +1,4 @@ +--- +upgrade: + - | + This library no longer supports Windows Operating Systems. diff --git a/vif_plug_ovs/constants.py b/vif_plug_ovs/constants.py index 867a3250..2431bcca 100644 --- a/vif_plug_ovs/constants.py +++ b/vif_plug_ovs/constants.py @@ -19,9 +19,6 @@ OVS_VHOSTUSER_PREFIX = 'vhu' OVS_DATAPATH_SYSTEM = 'system' OVS_DATAPATH_NETDEV = 'netdev' -PLATFORM_LINUX = 'linux2' -PLATFORM_WIN32 = 'win32' - OVS_DPDK_INTERFACE_TYPE = 'dpdk' # Neutron dead VLAN. diff --git a/vif_plug_ovs/linux_net.py b/vif_plug_ovs/linux_net.py index c780ec39..df76ea31 100644 --- a/vif_plug_ovs/linux_net.py +++ b/vif_plug_ovs/linux_net.py @@ -22,14 +22,12 @@ import glob import os import re -import sys from os_vif.internal.ip.api import ip as ip_lib from oslo_concurrency import processutils from oslo_log import log as logging from oslo_utils import excutils -from vif_plug_ovs import constants from vif_plug_ovs import exception from vif_plug_ovs import privsep @@ -55,12 +53,7 @@ NIC_NAME_LEN = 14 def _update_device_mtu(dev, mtu): if not mtu: return - if sys.platform != constants.PLATFORM_WIN32: - # Hyper-V with OVS does not support external programming of - # virtual interface MTUs via netsh or other Windows tools. - # When plugging an interface on Windows, we therefore skip - # programming the MTU and fallback to DHCP advertisement. - set_device_mtu(dev, mtu) + set_device_mtu(dev, mtu) @privsep.vif_plug.entrypoint diff --git a/vif_plug_ovs/ovs.py b/vif_plug_ovs/ovs.py index 4a719ea7..7372afec 100644 --- a/vif_plug_ovs/ovs.py +++ b/vif_plug_ovs/ovs.py @@ -17,8 +17,6 @@ # License for the specific language governing permissions and limitations # under the License. -import sys - from oslo_config import cfg from oslo_log import log as logging @@ -27,7 +25,6 @@ from os_vif.internal.ip.api import ip as ip_lib from os_vif import objects from os_vif import plugin - from vif_plug_ovs import constants from vif_plug_ovs import exception from vif_plug_ovs import linux_net @@ -181,9 +178,6 @@ class OvsPlugin(plugin.PluginBase): def supports_tc_qdisc(self, vif) -> bool: if self._get_vif_datapath_type(vif) != constants.OVS_DATAPATH_SYSTEM: return False - if sys.platform == constants.PLATFORM_WIN32: - return False - return True def _isolate_vif(self, vif_name, bridge): @@ -283,14 +277,6 @@ class OvsPlugin(plugin.PluginBase): linux_net.update_veth_pair(v1_name, v2_name, mtu) self._update_vif_port(vif, v2_name) - def _plug_vif_windows(self, vif, instance_info): - """Create a per-VIF OVS port.""" - - if not ip_lib.exists(vif.id): - self.ovsdb.ensure_ovs_bridge(vif.network.bridge, - self._get_vif_datapath_type(vif)) - self._create_vif_port(vif, vif.id, instance_info) - def _plug_port_bridge(self, vif, instance_info): """Create a per-VIF OVS bridge and patch pair.""" @@ -381,15 +367,7 @@ class OvsPlugin(plugin.PluginBase): raise exception.WrongPortProfile( profile=vif.port_profile.__class__.__name__) - if sys.platform == constants.PLATFORM_WIN32: - if type(vif) not in ( - objects.vif.VIFOpenVSwitch, objects.vif.VIFBridge - ): - raise osv_exception.PlugException( - vif=vif, err="This vif type is not supported on Windows") - - self._plug_vif_windows(vif, instance_info) - elif isinstance(vif, objects.vif.VIFOpenVSwitch): + if isinstance(vif, objects.vif.VIFOpenVSwitch): if self.config.per_port_bridge: self._plug_port_bridge(vif, instance_info) else: @@ -443,12 +421,6 @@ class OvsPlugin(plugin.PluginBase): qos_type = self.config.default_qos_type return qos_type - def _unplug_vif_windows(self, vif, instance_info): - """Remove port from OVS.""" - self.ovsdb.delete_ovs_vif_port(vif.network.bridge, vif.id, - delete_netdev=False) - self._delete_bridge_if_trunk(vif) - def _unplug_port_bridge(self, vif, instance_info): """Create a per-VIF OVS bridge and patch pair.""" # NOTE(sean-k-mooney): the port name prefix should not be @@ -508,14 +480,7 @@ class OvsPlugin(plugin.PluginBase): objects.vif.VIFPortProfileOpenVSwitch): raise exception.WrongPortProfile( profile=vif.port_profile.__class__.__name__) - if sys.platform == constants.PLATFORM_WIN32: - if type(vif) not in ( - objects.vif.VIFOpenVSwitch, objects.vif.VIFBridge - ): - raise osv_exception.UnplugException( - vif=vif, err="This vif type is not supported on windows.") - self._unplug_vif_windows(vif, instance_info) - elif isinstance(vif, objects.vif.VIFOpenVSwitch): + if isinstance(vif, objects.vif.VIFOpenVSwitch): if self.config.per_port_bridge: self._unplug_port_bridge(vif, instance_info) else: diff --git a/vif_plug_ovs/ovsdb/ovsdb_lib.py b/vif_plug_ovs/ovsdb/ovsdb_lib.py index f88f5672..9c509d63 100644 --- a/vif_plug_ovs/ovsdb/ovsdb_lib.py +++ b/vif_plug_ovs/ovsdb/ovsdb_lib.py @@ -10,7 +10,6 @@ # License for the specific language governing permissions and limitations # under the License. -import sys import uuid from oslo_log import log as logging @@ -59,12 +58,7 @@ class BaseOVS(object): if interface_type not in [ constants.OVS_VHOSTUSER_INTERFACE_TYPE, constants.OVS_VHOSTUSER_CLIENT_INTERFACE_TYPE]: - if sys.platform != constants.PLATFORM_WIN32: - # Hyper-V with OVS does not support external programming of - # virtual interface MTUs via netsh or other Windows tools. - # When plugging an interface on Windows, we therefore skip - # programming the MTU and fallback to DHCP advertisement. - linux_net.set_device_mtu(dev, mtu) + linux_net.set_device_mtu(dev, mtu) elif self._ovs_supports_mtu_requests(): self._set_mtu_request(txn, dev, mtu) else: diff --git a/vif_plug_ovs/tests/unit/ovsdb/test_ovsdb_lib.py b/vif_plug_ovs/tests/unit/ovsdb/test_ovsdb_lib.py index 7251154a..498c2b1f 100644 --- a/vif_plug_ovs/tests/unit/ovsdb/test_ovsdb_lib.py +++ b/vif_plug_ovs/tests/unit/ovsdb/test_ovsdb_lib.py @@ -53,24 +53,14 @@ class BaseOVSTest(testtools.TestCase): calls = [mock.call('Interface', 'device', ('mtu_request', 1500))] self.mock_db_set.assert_has_calls(calls) - @mock.patch('sys.platform', constants.PLATFORM_LINUX) @mock.patch.object(linux_net, 'set_device_mtu') - def test__update_device_mtu_interface_not_vhostuser_linux(self, + def test__update_device_mtu_interface_not_vhostuser(self, mock_set_device_mtu): self.br.update_device_mtu( self.mock_transaction, 'device', 1500, 'not_vhost' ) mock_set_device_mtu.assert_has_calls([mock.call('device', 1500)]) - @mock.patch('sys.platform', constants.PLATFORM_WIN32) - @mock.patch.object(linux_net, 'set_device_mtu') - def test__update_device_mtu_interface_not_vhostuser_windows(self, - mock_set_device_mtu): - self.br.update_device_mtu( - self.mock_transaction, 'device', 1500, 'not_vhost' - ) - mock_set_device_mtu.assert_not_called() - def test__update_device_mtu_interface_vhostuser_supports_mtu_req(self): with mock.patch.object(self.br, '_ovs_supports_mtu_requests', return_value=True), \ diff --git a/vif_plug_ovs/tests/unit/test_plugin.py b/vif_plug_ovs/tests/unit/test_plugin.py index 83cc9c3c..de157de5 100644 --- a/vif_plug_ovs/tests/unit/test_plugin.py +++ b/vif_plug_ovs/tests/unit/test_plugin.py @@ -238,20 +238,16 @@ class PluginTest(testtools.TestCase): mtu=plugin.config.network_device_mtu, interface_type=constants.OVS_VHOSTUSER_INTERFACE_TYPE) - @mock.patch.object(ovs, 'sys') @mock.patch.object(ovs.OvsPlugin, '_plug_vif_generic') - def test_plug_ovs_port_bridge_false(self, plug_vif_generic, mock_sys): - mock_sys.platform = 'linux' + def test_plug_ovs_port_bridge_false(self, plug_vif_generic): plugin = ovs.OvsPlugin.load(constants.PLUGIN_NAME) with mock.patch.object(plugin.config, 'per_port_bridge', False): plugin.plug(self.vif_ovs, self.instance) plug_vif_generic.assert_called_once_with( self.vif_ovs, self.instance) - @mock.patch.object(ovs, 'sys') @mock.patch.object(ovs.OvsPlugin, '_plug_port_bridge') - def test_plug_ovs_port_bridge_true(self, plug_vif, mock_sys): - mock_sys.platform = 'linux' + def test_plug_ovs_port_bridge_true(self, plug_vif): plugin = ovs.OvsPlugin.load(constants.PLUGIN_NAME) with mock.patch.object(plugin.config, 'per_port_bridge', True): plugin.plug(self.vif_ovs, self.instance) @@ -276,8 +272,7 @@ class PluginTest(testtools.TestCase): @mock.patch.object(linux_net, 'create_veth_pair') @mock.patch.object(ip_lib, 'exists') @mock.patch.object(linux_net, 'ensure_bridge') - @mock.patch.object(ovs, 'sys') - def test_plug_ovs_bridge(self, mock_sys, ensure_bridge, device_exists, + def test_plug_ovs_bridge(self, ensure_bridge, device_exists, create_veth_pair, update_veth_pair, add_bridge_port, _create_vif_port, _update_vif_port, ensure_ovs_bridge, @@ -307,7 +302,6 @@ class PluginTest(testtools.TestCase): # plugging new devices should result in devices being created device_exists.return_value = False - mock_sys.platform = 'linux' plugin = ovs.OvsPlugin.load(constants.PLUGIN_NAME) plugin.plug(self.vif_ovs_hybrid, self.instance) ensure_bridge.assert_has_calls(calls['ensure_bridge']) @@ -333,38 +327,10 @@ class PluginTest(testtools.TestCase): update_veth_pair.assert_has_calls(calls['update_veth_pair']) _update_vif_port.assert_has_calls(calls['_update_vif_port']) - @mock.patch.object(ovsdb_lib.BaseOVS, 'ensure_ovs_bridge') - @mock.patch.object(ovs.OvsPlugin, '_create_vif_port') - @mock.patch.object(ip_lib, 'exists', return_value=False) - @mock.patch.object(ovs, 'sys') - def _check_plug_ovs_windows(self, vif, mock_sys, mock_exists, - _create_vif_port, ensure_ovs_bridge): - dp_type = ovs.OvsPlugin._get_vif_datapath_type(vif) - calls = { - 'exists': [mock.call(vif.id)], - '_create_vif_port': [mock.call(vif, vif.id, self.instance)], - 'ensure_ovs_bridge': [mock.call('br0', dp_type)] - } - - mock_sys.platform = constants.PLATFORM_WIN32 - plugin = ovs.OvsPlugin.load(constants.PLUGIN_NAME) - plugin.plug(vif, self.instance) - mock_exists.assert_has_calls(calls['exists']) - _create_vif_port.assert_has_calls(calls['_create_vif_port']) - ensure_ovs_bridge.assert_has_calls(calls['ensure_ovs_bridge']) - - def test_plug_ovs_windows(self): - self._check_plug_ovs_windows(self.vif_ovs) - - def test_plug_ovs_bridge_windows(self): - self._check_plug_ovs_windows(self.vif_ovs_hybrid) - @mock.patch.object(ovsdb_lib.BaseOVS, 'delete_ovs_bridge') - @mock.patch.object(ovs, 'sys') @mock.patch.object(ovs.OvsPlugin, '_unplug_vif_generic') - def test_unplug_ovs_port_bridge_false(self, unplug, mock_sys, + def test_unplug_ovs_port_bridge_false(self, unplug, delete_ovs_bridge): - mock_sys.platform = 'linux' plugin = ovs.OvsPlugin.load(constants.PLUGIN_NAME) with mock.patch.object(plugin.config, 'per_port_bridge', False): plugin.unplug(self.vif_ovs, self.instance) @@ -372,11 +338,9 @@ class PluginTest(testtools.TestCase): delete_ovs_bridge.assert_not_called() @mock.patch.object(ovsdb_lib.BaseOVS, 'delete_ovs_bridge') - @mock.patch.object(ovs, 'sys') @mock.patch.object(ovs.OvsPlugin, '_unplug_port_bridge') - def test_unplug_ovs_port_bridge_true(self, unplug, mock_sys, + def test_unplug_ovs_port_bridge_true(self, unplug, delete_ovs_bridge): - mock_sys.platform = 'linux' plugin = ovs.OvsPlugin.load(constants.PLUGIN_NAME) with mock.patch.object(plugin.config, 'per_port_bridge', True): plugin.unplug(self.vif_ovs, self.instance) @@ -394,8 +358,7 @@ class PluginTest(testtools.TestCase): @mock.patch.object(ovsdb_lib.BaseOVS, 'delete_ovs_bridge') @mock.patch.object(ovsdb_lib.BaseOVS, 'delete_ovs_vif_port') @mock.patch.object(linux_net, 'delete_bridge') - @mock.patch.object(ovs, 'sys') - def test_unplug_ovs_bridge(self, mock_sys, delete_bridge, + def test_unplug_ovs_bridge(self, delete_bridge, delete_ovs_vif_port, delete_ovs_bridge): calls = { 'delete_bridge': [mock.call('qbrvif-xxx-yyy', 'qvbb679325f-ca')], @@ -403,32 +366,12 @@ class PluginTest(testtools.TestCase): 'br0', 'qvob679325f-ca', qos_type='linux-noop' )] } - mock_sys.platform = 'linux' plugin = ovs.OvsPlugin.load(constants.PLUGIN_NAME) plugin.unplug(self.vif_ovs_hybrid, self.instance) delete_bridge.assert_has_calls(calls['delete_bridge']) delete_ovs_vif_port.assert_has_calls(calls['delete_ovs_vif_port']) delete_ovs_bridge.assert_not_called() - @mock.patch.object(ovsdb_lib.BaseOVS, 'delete_ovs_vif_port') - @mock.patch.object(ovs, 'sys') - def _check_unplug_ovs_windows(self, vif, mock_sys, delete_ovs_vif_port): - mock_sys.platform = constants.PLATFORM_WIN32 - plugin = ovs.OvsPlugin.load(constants.PLUGIN_NAME) - plugin.unplug(vif, self.instance) - delete_ovs_vif_port.assert_called_once_with('br0', vif.id, - delete_netdev=False) - - @mock.patch.object(ovsdb_lib.BaseOVS, 'delete_ovs_bridge') - def test_unplug_ovs_windows(self, delete_ovs_bridge): - self._check_unplug_ovs_windows(self.vif_ovs) - delete_ovs_bridge.assert_not_called() - - @mock.patch.object(ovsdb_lib.BaseOVS, 'delete_ovs_bridge') - def test_unplug_ovs_bridge_windows(self, delete_ovs_bridge): - self._check_unplug_ovs_windows(self.vif_ovs_hybrid) - delete_ovs_bridge.assert_not_called() - @mock.patch.object(ovs.OvsPlugin, '_create_vif_port') def test_plug_ovs_vhostuser(self, _create_vif_port): dp_type = ovs.OvsPlugin._get_vif_datapath_type(self.vif_vhostuser)