Drop Windows platform support from ovsdbapp
Open vSwitch 4.0.0 removes Windows support [1], including ``python-ovs`` helpers such as ``winutils`` used by ovsdbapp's Windows IDL connection code. Remove the ``windows`` backend, platform checks in ``connection``, ``idlutils.row_by_record()`` and ``vlog.use_python_logger()``, and related unit tests. Document Unix-like platforms as the supported target and add a release note for deployers. [1]https://github.com/openvswitch/ovs/commit/965eb1f87a4d47be1d86483df7d93f7a37da4961 Closes-Bug: #2168950 Assisted-By: Composer 2.5 Signed-off-by: Rodolfo Alonso <rodolfo.ah@gmail.com> Change-Id: I617c04c1b4fe48d4c5f9d336f1df0c68e6dd1039
This commit is contained in:
1 parent
0ece018396
commit
837b38b232
10 files changed
+17
-157
No files matched your search
+4
-2
@@ -8,9 +8,11 @@ ovsdbapp
|
||||
|
||||
A library for creating OVSDB applications
|
||||
|
||||
The ovdsbapp library is useful for creating applications that communicate
|
||||
The ovsdbapp library is useful for creating applications that communicate
|
||||
via Open_vSwitch's OVSDB protocol (https://tools.ietf.org/html/rfc7047). It
|
||||
wraps the Python 'ovs' and adds an event loop and friendly transactions.
|
||||
wraps the Python ``ovs`` package and adds an event loop and friendly
|
||||
transactions. ovsdbapp targets Unix-like systems where Open vSwitch and
|
||||
``python-ovs`` are supported.
|
||||
|
||||
* Free software: Apache license
|
||||
* Source: https://opendev.org/openstack/ovsdbapp/
|
||||
|
||||
@@ -2,6 +2,9 @@
|
||||
Installation
|
||||
============
|
||||
|
||||
ovsdbapp is supported on Unix-like platforms with Open vSwitch and the
|
||||
``python-ovs`` bindings. Microsoft Windows is not supported.
|
||||
|
||||
At the command line::
|
||||
|
||||
$ pip install ovsdbapp
|
||||
|
||||
@@ -13,7 +13,6 @@
|
||||
# under the License.
|
||||
|
||||
import logging
|
||||
import os
|
||||
import queue
|
||||
import threading
|
||||
import time
|
||||
@@ -24,13 +23,9 @@ from ovs.db import idl
|
||||
from ovs import poller
|
||||
|
||||
from ovsdbapp.backend.ovs_idl import idlutils
|
||||
from ovsdbapp.backend.ovs_idl.linux import connection_utils
|
||||
from ovsdbapp import exceptions
|
||||
|
||||
if os.name == 'nt':
|
||||
from ovsdbapp.backend.ovs_idl.windows import connection_utils
|
||||
else:
|
||||
from ovsdbapp.backend.ovs_idl.linux import connection_utils
|
||||
|
||||
LOG = logging.getLogger(__name__)
|
||||
|
||||
|
||||
|
||||
@@ -20,7 +20,6 @@ import functools
|
||||
import json
|
||||
import logging
|
||||
import os
|
||||
import sys
|
||||
import time
|
||||
import uuid
|
||||
|
||||
@@ -127,16 +126,7 @@ def row_by_record(idl_, table, record):
|
||||
# Not a UUID string, continue lookup by other means
|
||||
pass
|
||||
except KeyError as e:
|
||||
if sys.platform != 'win32':
|
||||
# On Windows the name of the ports is described by the OVS schema:
|
||||
# https://tinyurl.com/zk8skhx
|
||||
# Is a UUID. (This is due to the fact on Windows port names don't
|
||||
# have the 16 chars length limitation as for Linux). Because of
|
||||
# this uuid.UUID(record) will not raise a ValueError exception
|
||||
# as it happens on Linux and will try to fetch the directly
|
||||
# the column instead of using the lookup table. This will raise
|
||||
# a KeyError exception on Windows.
|
||||
raise RowNotFound(table=table, col='uuid', match=record) from e
|
||||
raise RowNotFound(table=table, col='uuid', match=record) from e
|
||||
|
||||
rl = _LOOKUP_TABLE.get(table, RowLookup(table, get_index_column(t), None))
|
||||
# no table means uuid only, no column means lookup table only has one row
|
||||
|
||||
@@ -14,18 +14,9 @@
|
||||
|
||||
import collections
|
||||
import logging
|
||||
import sys
|
||||
|
||||
from ovs import vlog
|
||||
|
||||
try:
|
||||
from eventlet import patcher
|
||||
# If eventlet is installed and the 'thread' module is patched, we will
|
||||
# skip setting up the python logger on Windows.
|
||||
EVENTLET_NONBLOCKING_MODE_ENABLED = patcher.is_monkey_patched('thread')
|
||||
except ImportError:
|
||||
EVENTLET_NONBLOCKING_MODE_ENABLED = False
|
||||
|
||||
_LOG = logging.getLogger(__name__)
|
||||
|
||||
# Map local log LEVELS to local LOG functions
|
||||
@@ -63,17 +54,6 @@ def use_python_logger(levels=ALL_LEVELS, max_level=None):
|
||||
:param: max_level: the maximum level to log
|
||||
:type: max_level: vlog level, CRITICAL, ERROR, WARN, INFO, or DEBUG
|
||||
"""
|
||||
if sys.platform == 'win32' and EVENTLET_NONBLOCKING_MODE_ENABLED:
|
||||
# NOTE(abalutoiu) When using oslo logging we need to keep in mind that
|
||||
# it does not work well with native threads. We need to be careful when
|
||||
# we call eventlet.tpool.execute, and make sure that it will not use
|
||||
# the oslo logging, since it might cause unexpected hangs if
|
||||
# greenthreads are used. On Windows we have to use
|
||||
# eventlet.tpool.execute for a call to the ovs lib which will use
|
||||
# vlog to log messages. We will skip replacing the OVS IDL logger
|
||||
# functions on Windows to avoid unexpected hangs with oslo logging
|
||||
return
|
||||
|
||||
if max_level:
|
||||
levels = levels[:levels.index(max_level) + 1]
|
||||
|
||||
|
||||
Whitespace-only changes.
@@ -1,61 +0,0 @@
|
||||
# Copyright 2017 Cloudbase Solutions Srl
|
||||
#
|
||||
# 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 ovs import poller
|
||||
from ovs import winutils
|
||||
|
||||
from ovsdbapp.backend.ovs_idl.common import base_connection_utils
|
||||
from ovsdbapp.backend.ovs_idl.windows import utils
|
||||
|
||||
|
||||
class WaitQueue(base_connection_utils.WaitQueue):
|
||||
def init_alert_notification(self):
|
||||
# We will use an event to get signaled when there is something in
|
||||
# the queue. The OVS poller can wait on events on Windows.
|
||||
# NOTE(abalutoiu) The assumption made is that the queue has
|
||||
# length 1, otherwise we will need to have a list of events with
|
||||
# the size of the queue.
|
||||
self.alert_event = winutils.get_new_event(bManualReset=True,
|
||||
bInitialState=False)
|
||||
|
||||
def alert_notification_consume(self):
|
||||
# Set the event object to the nonsignaled state to indicate that
|
||||
# the queue is empty.
|
||||
winutils.win32event.ResetEvent(self.alert_event)
|
||||
|
||||
def alert_notify(self):
|
||||
# Set the event object to the signaled state to indicate that
|
||||
# we have something in the queue.
|
||||
winutils.win32event.SetEvent(self.alert_event)
|
||||
|
||||
@property
|
||||
def alert_fileno(self):
|
||||
return self.alert_event
|
||||
|
||||
def close(self):
|
||||
pass
|
||||
|
||||
|
||||
def monkey_patch_poller_support():
|
||||
# Ensure that WaitForMultipleObjects will not block other greenthreads.
|
||||
# poller.block uses WaitForMultipleObjects on Windows
|
||||
old_block = poller.Poller.block
|
||||
|
||||
def new_block(self):
|
||||
return utils.avoid_blocking_call(old_block, self)
|
||||
|
||||
poller.Poller.block = new_block
|
||||
|
||||
|
||||
monkey_patch_poller_support()
|
||||
@@ -1,42 +0,0 @@
|
||||
# Copyright 2017 Cloudbase Solutions Srl
|
||||
#
|
||||
# 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.
|
||||
|
||||
|
||||
try:
|
||||
import eventlet
|
||||
from eventlet import tpool
|
||||
except ImportError:
|
||||
eventlet = None
|
||||
|
||||
|
||||
def avoid_blocking_call(f, *args, **kwargs):
|
||||
"""Ensure that the method "f" will not block other greenthreads.
|
||||
|
||||
Performs the call to the function "f" received as parameter in a
|
||||
different thread using tpool.execute when called from a greenthread.
|
||||
This will ensure that the function "f" will not block other greenthreads.
|
||||
If not called from a greenthread, it will invoke the function "f" directly.
|
||||
The function "f" will receive as parameters the arguments "args" and
|
||||
keyword arguments "kwargs". If eventlet is not installed on the system
|
||||
then this will call directly the function "f".
|
||||
"""
|
||||
if eventlet is None:
|
||||
return f(*args, **kwargs)
|
||||
|
||||
# Note that eventlet.getcurrent will always return a greenlet object.
|
||||
# In case of a greenthread, the parent greenlet will always be the hub
|
||||
# loop greenlet.
|
||||
if eventlet.getcurrent().parent:
|
||||
return tpool.execute(f, *args, **kwargs)
|
||||
return f(*args, **kwargs)
|
||||
@@ -161,8 +161,7 @@ class TestIdlUtils(base.TestCase):
|
||||
obj = MockCommand("test")
|
||||
self.assertEqual("test", idlutils.db_replace_record(obj))
|
||||
|
||||
@mock.patch('sys.platform', 'linux2')
|
||||
def test_row_by_record_linux(self):
|
||||
def test_row_by_record(self):
|
||||
FAKE_RECORD = 'fake_record'
|
||||
mock_idl_ = mock.MagicMock()
|
||||
mock_table = mock.MagicMock(
|
||||
@@ -174,19 +173,6 @@ class TestIdlUtils(base.TestCase):
|
||||
FAKE_RECORD)
|
||||
self.assertEqual(mock.sentinel.row_value, res)
|
||||
|
||||
@mock.patch('sys.platform', 'win32')
|
||||
def test_row_by_record_win(self):
|
||||
FAKE_RECORD_GUID = '7b0f349d-5524-4d36-afff-5222b9fdee8c'
|
||||
mock_idl_ = mock.MagicMock()
|
||||
mock_table = mock.MagicMock(
|
||||
rows={mock.sentinel.row: mock.sentinel.row_value})
|
||||
mock_idl_.tables = {mock.sentinel.table_name: mock_table}
|
||||
|
||||
res = idlutils.row_by_record(mock_idl_,
|
||||
mock.sentinel.table_name,
|
||||
FAKE_RECORD_GUID)
|
||||
self.assertEqual(mock.sentinel.row_value, res)
|
||||
|
||||
def test_index_name(self):
|
||||
expected = {
|
||||
('one',): 'one',
|
||||
|
||||
@@ -0,0 +1,7 @@
|
||||
---
|
||||
upgrade:
|
||||
- |
|
||||
Support for running ovsdbapp on Microsoft Windows has been removed.
|
||||
Open vSwitch removed Windows support in version 4.0.0, including the
|
||||
``python-ovs`` APIs ovsdbapp relied on for Windows-specific IDL
|
||||
connection handling. ovsdbapp now targets Unix-like systems only.
|
||||
Reference in new issue
Block a user