Clean up Windows support

It was deprecated in 3.4.0[1], which was released during 2024.1 cycle.

[1] 077e43698e

Change-Id: Ic896b54c4858566e56389e1bf961bb1765d8bbf0
This commit is contained in:
Takashi Kajinami 2024-10-16 02:13:29 +09:00
parent 2df01e8845
commit 71521590da
13 changed files with 20 additions and 256 deletions

View File

@ -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()

View File

@ -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')

View File

@ -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
def test_get_impl(self):
self.assertIsInstance(api.ip, impl_pyroute2.PyRoute2)

View File

@ -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)

View File

@ -0,0 +1,4 @@
---
upgrade:
- |
This library no longer supports Windows Operating Systems.

View File

@ -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.

View File

@ -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,11 +53,6 @@ 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)

View File

@ -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:

View File

@ -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,11 +58,6 @@ 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)
elif self._ovs_supports_mtu_requests():
self._set_mtu_request(txn, dev, mtu)

View File

@ -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), \

View File

@ -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)