Neutron support for fast path stack
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

server.py 5.1KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144
  1. # Copyright 2016 6WIND S.A.
  2. #
  3. # Licensed under the Apache License, Version 2.0 (the "License"); you may
  4. # not use this file except in compliance with the License. You may obtain
  5. # a copy of the License at
  6. #
  7. # http://www.apache.org/licenses/LICENSE-2.0
  8. #
  9. # Unless required by applicable law or agreed to in writing, software
  10. # distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
  11. # WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
  12. # License for the specific language governing permissions and limitations
  13. # under the License.
  14. import datetime
  15. import os
  16. from networking_6wind.common import constants
  17. from neutron._i18n import _LE
  18. from neutron.agent import rpc as agent_rpc
  19. from neutron.common import topics
  20. from neutron import context
  21. from neutron import manager
  22. from neutron_lib import constants as n_constants
  23. from oslo_config import cfg
  24. from oslo_log import log as logging
  25. from oslo_service import loopingcall
  26. from pkg_resources import parse_version as V
  27. cfg.CONF.import_group('vhostuser', 'networking_6wind.common.config')
  28. LOG = logging.getLogger(__name__)
  29. class NeutronFastPathAgent(manager.Manager):
  30. def __init__(self, host, conf=None):
  31. self.conf = conf or cfg.CONF
  32. self.fp_info = {
  33. 'timestamp': '',
  34. 'product': 'unknown',
  35. 'product_version': 'unknown',
  36. 'active': False,
  37. 'vhostuser_socket_dir': self.conf.vhostuser.socket_dir,
  38. 'vhostuser_socket_prefix': self.conf.vhostuser.socket_prefix,
  39. 'vhostuser_socket_mode': self.conf.vhostuser.mode,
  40. 'supported_plugs': [],
  41. }
  42. self.agent_state = {
  43. 'binary': 'neutron-fastpath-agent',
  44. 'host': cfg.CONF.host,
  45. 'topic': n_constants.L2_AGENT_TOPIC,
  46. 'configurations': self.fp_info,
  47. 'start_flag': True,
  48. 'agent_type': constants.FP_AGENT_TYPE,
  49. }
  50. self.ctx = context.get_admin_context_without_session()
  51. self._setup_rpc()
  52. self.init_host()
  53. def init_host(self):
  54. self._init_fp_info()
  55. def _update_fp_status(self, fp_info_dict):
  56. timestamp = datetime.datetime.now().strftime("%Y-%m-%d %H:%M:%S")
  57. fp_info_dict['timestamp'] = timestamp
  58. try:
  59. status = os.system('pidof fp-rte')
  60. if status == 0:
  61. fp_info_dict['active'] = True
  62. else:
  63. fp_info_dict['active'] = False
  64. except Exception:
  65. fp_info_dict['active'] = False
  66. def _init_fp_info(self):
  67. with open('/usr/local/etc/6WIND_product') as f:
  68. self.fp_info['product'] = f.read(2048).rstrip()
  69. with open('/usr/local/etc/6WIND_product_version') as f:
  70. self.fp_info['product_version'] = f.read(2048).rstrip()
  71. self._update_fp_status(self.fp_info)
  72. fp_product_version = self.fp_info['product_version']
  73. if self.fp_info['product'] == 'virtual-accelerator':
  74. self.fp_info['supported_plugs'] = ['ovs', 'bridge']
  75. try:
  76. if V(fp_product_version) >= V('1.4.0'):
  77. self.fp_info['supported_plugs'].append('tap')
  78. except Exception:
  79. pass
  80. elif self.fp_info['product'] == '6windgate':
  81. self.fp_info['supported_plugs'] = ['ovs', 'bridge']
  82. try:
  83. if V(fp_product_version) >= V('4.13.0'):
  84. self.fp_info['supported_plugs'].append('tap')
  85. except Exception:
  86. pass
  87. def _report_state(self):
  88. self._update_fp_status(self.fp_info)
  89. try:
  90. self.state_rpc.report_state(self.ctx, self.agent_state, True)
  91. self.agent_state.pop('start_flag', None)
  92. except AttributeError:
  93. # This means the server does not support report_state
  94. LOG.warning("Neutron server does not support state report. "
  95. "State report for this agent will be disabled.")
  96. self.heartbeat.stop()
  97. return
  98. except Exception:
  99. LOG.exception(_LE("Failed reporting state!"))
  100. def get_fp_info(self):
  101. # check if fp is running and fill agent configurations
  102. fp_info_copy = self.agent_state['configurations'].copy()
  103. self._update_fp_status(fp_info_copy)
  104. return fp_info_copy
  105. def _setup_rpc(self):
  106. self.topic = "FP_AGENT"
  107. self.state_rpc = agent_rpc.PluginReportStateAPI(topics.REPORTS)
  108. # RPC network init
  109. # Handle updates from service
  110. self.endpoints = [self]
  111. # Define the listening consumers for the agent
  112. consumers = [["info", "update"]]
  113. self.connection = agent_rpc.create_consumers(self.endpoints,
  114. self.topic,
  115. consumers,
  116. start_listening=False)
  117. report_interval = 30
  118. if report_interval:
  119. self.heartbeat = loopingcall.FixedIntervalLoopingCall(
  120. self._report_state)
  121. self.heartbeat.start(interval=report_interval)