Browse Source

Deprecate XenAPI support

The configuration options are now marked as deprecated for
removal in X release.

Any related code is deleted. Neutron does not support XenAPI,
same as Nova [1][2].

[1]https://review.opendev.org/#/c/749304/
[2]https://review.opendev.org/#/c/749309/

Change-Id: Ifdb2200a5dac3508fdf8907bdd1f4547dff35341
Story: #2007686
Task: #41269
changes/34/763034/6
Rodolfo Alonso Hernandez 7 months ago
parent
commit
a6dbf97242
12 changed files with 23 additions and 233 deletions
  1. +0
    -1
      etc/oslo-config-generator/openvswitch_agent.ini
  2. +0
    -1
      lower-constraints.txt
  3. +2
    -7
      neutron/agent/linux/utils.py
  4. +0
    -92
      neutron/agent/linux/xenapi_root_helper.py
  5. +0
    -4
      neutron/conf/agent/common.py
  6. +14
    -8
      neutron/conf/agent/xenapi_conf.py
  7. +0
    -8
      neutron/opts.py
  8. +0
    -15
      neutron/plugins/ml2/drivers/openvswitch/agent/ovs_neutron_agent.py
  9. +0
    -10
      neutron/tests/unit/agent/linux/test_utils.py
  10. +0
    -86
      neutron/tests/unit/agent/linux/test_xenapi_root_helper.py
  11. +7
    -0
      releasenotes/notes/remove_xenapi_support-2cc2a4b9ad0ef01d.yaml
  12. +0
    -1
      requirements.txt

+ 0
- 1
etc/oslo-config-generator/openvswitch_agent.ini View File

@ -3,5 +3,4 @@ output_file = etc/neutron/plugins/ml2/openvswitch_agent.ini.sample
wrap_width = 79
namespace = neutron.ml2.ovs.agent
namespace = neutron.ml2.xenapi
namespace = oslo.log

+ 0
- 1
lower-constraints.txt View File

@ -58,7 +58,6 @@ os-client-config==1.28.0
os-ken==0.3.0
os-service-types==1.7.0
os-vif==1.15.1
os-xenapi==0.3.4
osc-lib==1.8.0
oslo.cache==1.26.0
oslo.concurrency==3.26.0


+ 2
- 7
neutron/agent/linux/utils.py View File

@ -36,7 +36,6 @@ from oslo_utils import fileutils
import psutil
from neutron._i18n import _
from neutron.agent.linux import xenapi_root_helper
from neutron.common import utils
from neutron.conf.agent import common as config
from neutron import wsgi
@ -57,12 +56,8 @@ class RootwrapDaemonHelper(object):
def get_client(cls):
with cls.__lock:
if cls.__client is None:
if (xenapi_root_helper.ROOT_HELPER_DAEMON_TOKEN ==
cfg.CONF.AGENT.root_helper_daemon):
cls.__client = xenapi_root_helper.XenAPIClient()
else:
cls.__client = client.Client(
shlex.split(cfg.CONF.AGENT.root_helper_daemon))
cls.__client = client.Client(
shlex.split(cfg.CONF.AGENT.root_helper_daemon))
return cls.__client


+ 0
- 92
neutron/agent/linux/xenapi_root_helper.py View File

@ -1,92 +0,0 @@
# Copyright (c) 2016 Citrix System.
# All Rights Reserved.
#
# 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.
"""xenapi root helper
For xenapi, we may need to run some commands in dom0 with additional privilege.
This xenapi root helper contains the class of XenAPIClient to support it:
XenAPIClient will keep a XenAPI session to dom0 and allow to run commands
in dom0 via calling XenAPI plugin. The XenAPI plugin is responsible to
determine whether a command is safe to execute.
"""
from os_xenapi.client import session
from os_xenapi.client import XenAPI
from oslo_config import cfg
from oslo_log import log as logging
from oslo_rootwrap import cmd as oslo_rootwrap_cmd
from oslo_serialization import jsonutils
from neutron.conf.agent import xenapi_conf
ROOT_HELPER_DAEMON_TOKEN = 'xenapi_root_helper' # nosec
RC_UNKNOWN_XENAPI_ERROR = 80
MSG_UNAUTHORIZED = "Unauthorized command"
MSG_NOT_FOUND = "Executable not found"
XENAPI_PLUGIN_FAILURE_ID = "XENAPI_PLUGIN_FAILURE"
LOG = logging.getLogger(__name__)
xenapi_conf.register_xenapi_opts(cfg.CONF)
class XenAPIClient(object):
def __init__(self):
self._session = self._create_session(
cfg.CONF.xenapi.connection_url,
cfg.CONF.xenapi.connection_username,
cfg.CONF.xenapi.connection_password)
def _call_plugin(self, plugin, fn, args):
return self._session.call_plugin(plugin, fn, args)
def _create_session(self, url, username, password):
return session.XenAPISession(url, username, password,
originator="neutron")
def _get_return_code(self, failure_details):
# The details will be as:
# [XENAPI_PLUGIN_FAILURE_ID, methodname, except_class_name, message]
# We can distinguish the error type by checking the message string.
if (len(failure_details) == 4 and
XENAPI_PLUGIN_FAILURE_ID == failure_details[0]):
if (MSG_UNAUTHORIZED == failure_details[3]):
return oslo_rootwrap_cmd.RC_UNAUTHORIZED
elif (MSG_NOT_FOUND == failure_details[3]):
return oslo_rootwrap_cmd.RC_NOEXECFOUND
# otherwise we get unexpected exception.
return RC_UNKNOWN_XENAPI_ERROR
def execute(self, cmd, stdin=None):
out = ""
err = ""
if cmd is None or len(cmd) == 0:
err = "No command specified."
return oslo_rootwrap_cmd.RC_NOCOMMAND, out, err
try:
result_raw = self._call_plugin(
'netwrap.py', 'run_command',
{'cmd': jsonutils.dumps(cmd),
'cmd_input': jsonutils.dumps(stdin)})
result = jsonutils.loads(result_raw)
returncode = result['returncode']
out = result['out']
err = result['err']
return returncode, out, err
except XenAPI.Failure as failure:
LOG.exception('Failed to execute command: %s', cmd)
returncode = self._get_return_code(failure.details)
return returncode, out, err

+ 0
- 4
neutron/conf/agent/common.py View File

@ -105,10 +105,6 @@ in "daemon mode" which has been reported to improve performance at scale. For
more information on running rootwrap in "daemon mode", see:
https://docs.openstack.org/oslo.rootwrap/latest/user/usage.html#daemon-mode
For the agent which needs to execute commands in Dom0 in the hypervisor of
XenServer, this option should be set to 'xenapi_root_helper', so that it will
keep a XenAPI session to pass commands to Dom0.
""")),
]


+ 14
- 8
neutron/conf/agent/xenapi_conf.py View File

@ -17,20 +17,26 @@ from oslo_config import cfg
from neutron._i18n import _
XENAPI_CONF_SECTION = 'xenapi'
XENAPI_DEPRECATION_REASON = ('XenAPI support has been removed from Nova, it '
'will be removed in X.')
XENAPI_OPTS = [
cfg.StrOpt('connection_url',
help=_("URL for connection to XenServer/Xen Cloud Platform.")),
help=_("URL for connection to XenServer/Xen Cloud Platform."),
deprecated_for_removal=True,
deprecated_since='Wallaby',
deprecated_reason=XENAPI_DEPRECATION_REASON),
cfg.StrOpt('connection_username',
help=_("Username for connection to XenServer/Xen Cloud "
"Platform.")),
"Platform."),
deprecated_for_removal=True,
deprecated_since='Wallaby',
deprecated_reason=XENAPI_DEPRECATION_REASON),
cfg.StrOpt('connection_password',
help=_("Password for connection to XenServer/Xen Cloud "
"Platform."),
secret=True)
secret=True,
deprecated_for_removal=True,
deprecated_since='Wallaby',
deprecated_reason=XENAPI_DEPRECATION_REASON)
]
def register_xenapi_opts(cfg=cfg.CONF):
cfg.register_opts(XENAPI_OPTS, group=XENAPI_CONF_SECTION)

+ 0
- 8
neutron/opts.py View File

@ -31,7 +31,6 @@ import neutron.conf.agent.linux
import neutron.conf.agent.metadata.config as meta_conf
import neutron.conf.agent.ovs_conf
import neutron.conf.agent.ovsdb_api
import neutron.conf.agent.xenapi_conf
import neutron.conf.common
import neutron.conf.db.dvr_mac_db
import neutron.conf.db.extraroute_db
@ -341,10 +340,3 @@ def list_ironic_auth_opts():
opt_list.append(plugin_option)
opt_list.sort(key=operator.attrgetter('name'))
return [(IRONIC_GROUP, opt_list)]
def list_xenapi_opts():
return [
('xenapi',
neutron.conf.agent.xenapi_conf.XENAPI_OPTS)
]

+ 0
- 15
neutron/plugins/ml2/drivers/openvswitch/agent/ovs_neutron_agent.py View File

@ -53,7 +53,6 @@ from neutron.agent.common import ovs_lib
from neutron.agent.common import polling
from neutron.agent.common import utils
from neutron.agent.l2 import l2_agent_extensions_manager as ext_manager
from neutron.agent.linux import xenapi_root_helper
from neutron.agent import rpc as agent_rpc
from neutron.agent import securitygroups_rpc as agent_sg_rpc
from neutron.api.rpc.callbacks import resources
@ -62,7 +61,6 @@ from neutron.api.rpc.handlers import securitygroups_rpc as sg_rpc
from neutron.common import config
from neutron.common import utils as n_utils
from neutron.conf.agent import common as agent_config
from neutron.conf.agent import xenapi_conf
from neutron.conf import service as service_conf
from neutron.plugins.ml2.drivers.agent import capabilities
from neutron.plugins.ml2.drivers.l2pop.rpc_manager import l2population_rpc
@ -2769,20 +2767,7 @@ def validate_tunnel_config(tunnel_types, local_ip):
raise SystemExit(1)
def prepare_xen_compute():
is_xen_compute_host = 'rootwrap-xen-dom0' in cfg.CONF.AGENT.root_helper \
or xenapi_root_helper.ROOT_HELPER_DAEMON_TOKEN == \
cfg.CONF.AGENT.root_helper_daemon
if is_xen_compute_host:
xenapi_conf.register_xenapi_opts()
# Force ip_lib to always use the root helper to ensure that ip
# commands target xen dom0 rather than domU.
cfg.CONF.register_opts(ip_lib.OPTS)
cfg.CONF.set_default('ip_lib_force_root', True)
def main(bridge_classes):
prepare_xen_compute()
ovs_capabilities.register()
ext_manager.register_opts(cfg.CONF)
agent_config.setup_privsep()


+ 0
- 10
neutron/tests/unit/agent/linux/test_utils.py View File

@ -40,16 +40,6 @@ class AgentUtilsExecuteTest(base.BaseTestCase):
self.process.return_value.returncode = 0
self.mock_popen = self.process.return_value.communicate
def test_xenapi_root_helper(self):
token = utils.xenapi_root_helper.ROOT_HELPER_DAEMON_TOKEN
self.config(group='AGENT', root_helper_daemon=token)
with mock.patch(
'neutron.agent.linux.utils.xenapi_root_helper.XenAPIClient')\
as mock_xenapi_class:
mock_client = mock_xenapi_class.return_value
cmd_client = utils.RootwrapDaemonHelper.get_client()
self.assertEqual(cmd_client, mock_client)
def test_without_helper(self):
expected = "%s\n" % self.test_file
self.mock_popen.return_value = [expected, ""]


+ 0
- 86
neutron/tests/unit/agent/linux/test_xenapi_root_helper.py View File

@ -1,86 +0,0 @@
# Copyright 2016 Citrix System.
#
# 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
from oslo_config import cfg
from oslo_rootwrap import cmd as oslo_rootwrap_cmd
from neutron.agent.linux import xenapi_root_helper as helper
from neutron.conf.agent import xenapi_conf
from neutron.tests import base
class TestXenapiRootHelper(base.BaseTestCase):
def _get_fake_xenapi_client(self):
class FakeXenapiClient(helper.XenAPIClient):
def __init__(self):
self._session = mock.MagicMock()
return FakeXenapiClient()
def setUp(self):
super(TestXenapiRootHelper, self).setUp()
conf = cfg.CONF
xenapi_conf.register_xenapi_opts(conf)
def test_get_return_code_unauthourized(self):
failure_details = [helper.XENAPI_PLUGIN_FAILURE_ID,
'run_command',
'PluginError',
helper.MSG_UNAUTHORIZED]
xenapi_client = self._get_fake_xenapi_client()
rc = xenapi_client._get_return_code(failure_details)
self.assertEqual(oslo_rootwrap_cmd.RC_UNAUTHORIZED, rc)
def test_get_return_code_noexecfound(self):
failure_details = [helper.XENAPI_PLUGIN_FAILURE_ID,
'run_command',
'PluginError',
helper.MSG_NOT_FOUND]
xenapi_client = self._get_fake_xenapi_client()
rc = xenapi_client._get_return_code(failure_details)
self.assertEqual(oslo_rootwrap_cmd.RC_NOEXECFOUND, rc)
def test_get_return_code_unknown_error(self):
failure_details = [helper.XENAPI_PLUGIN_FAILURE_ID,
'run_command',
'PluginError',
'Any unknown error']
xenapi_client = self._get_fake_xenapi_client()
rc = xenapi_client._get_return_code(failure_details)
self.assertEqual(helper.RC_UNKNOWN_XENAPI_ERROR, rc)
def test_execute(self):
cmd = ["ovs-vsctl", "list-ports", "xapi2"]
expect_cmd_args = {'cmd': '["ovs-vsctl", "list-ports", "xapi2"]',
'cmd_input': 'null'}
raw_result = '{"returncode": 0, "err": "", "out": "vif158.2"}'
with mock.patch.object(helper.XenAPIClient, "_call_plugin",
return_value=raw_result) as mock_call_plugin:
xenapi_client = self._get_fake_xenapi_client()
rc, out, err = xenapi_client.execute(cmd)
mock_call_plugin.assert_called_once_with(
'netwrap.py', 'run_command', expect_cmd_args)
self.assertEqual(0, rc)
self.assertEqual("vif158.2", out)
self.assertEqual("", err)
def test_execute_nocommand(self):
cmd = []
xenapi_client = self._get_fake_xenapi_client()
rc, out, err = xenapi_client.execute(cmd)
self.assertEqual(oslo_rootwrap_cmd.RC_NOCOMMAND, rc)

+ 7
- 0
releasenotes/notes/remove_xenapi_support-2cc2a4b9ad0ef01d.yaml View File

@ -0,0 +1,7 @@
---
deprecations:
- |
Removed ``XenAPI`` support in Neutron. This driver is no longer supported
in Nova and Neutron.
The configuration options have been marked as "deprecated for removal" and
will be removed in X release.

+ 0
- 1
requirements.txt View File

@ -54,7 +54,6 @@ pyOpenSSL>=17.1.0 # Apache-2.0
python-novaclient>=9.1.0 # Apache-2.0
openstacksdk>=0.31.2 # Apache-2.0
python-designateclient>=2.7.0 # Apache-2.0
os-xenapi>=0.3.4 # Apache-2.0
os-vif>=1.15.1 # Apache-2.0
futurist>=1.2.0 # Apache-2.0
tooz>=1.58.0 # Apache-2.0


Loading…
Cancel
Save