os-ken/ryu/tests/integrated/common/ryubgp.py

213 lines
6.6 KiB
Python

# Copyright (C) 2016 Nippon Telegraph and Telephone Corporation.
#
# 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 __future__ import absolute_import
import logging
import os
import time
from . import docker_base as base
LOG = logging.getLogger(__name__)
class RyuBGPContainer(base.BGPContainer):
WAIT_FOR_BOOT = 1
SHARED_VOLUME = '/etc/ryu'
def __init__(self, name, asn, router_id, ctn_image_name):
super(RyuBGPContainer, self).__init__(name, asn, router_id,
ctn_image_name)
self.RYU_CONF = os.path.join(self.config_dir, 'ryu.conf')
self.SHARED_RYU_CONF = os.path.join(self.SHARED_VOLUME, 'ryu.conf')
self.SHARED_BGP_CONF = os.path.join(self.SHARED_VOLUME, 'bgp_conf.py')
self.shared_volumes.append((self.config_dir, self.SHARED_VOLUME))
def _create_config_ryu(self):
c = base.CmdBuffer()
c << '[DEFAULT]'
c << 'verbose=True'
c << 'log_file=/etc/ryu/manager.log'
with open(self.RYU_CONF, 'w') as f:
LOG.info("[%s's new config]" % self.name)
LOG.info(str(c))
f.writelines(str(c))
def _create_config_ryu_bgp(self):
c = base.CmdBuffer()
c << 'import os'
c << ''
c << 'BGP = {'
c << " 'local_as': %s," % str(self.asn)
c << " 'router_id': '%s'," % self.router_id
c << " 'neighbors': ["
c << " {"
for peer, info in self.peers.items():
n_addr = info['neigh_addr'].split('/')[0]
c << " 'address': '%s'," % n_addr
c << " 'remote_as': %s," % str(peer.asn)
c << " 'enable_ipv4': True,"
c << " 'enable_ipv6': True,"
c << " 'enable_vpnv4': True,"
c << " 'enable_vpnv6': True,"
c << ' },'
c << ' ],'
c << " 'routes': ["
for route in self.routes.values():
c << " {"
c << " 'prefix': '%s'," % route['prefix']
c << " },"
c << " ],"
c << "}"
log_conf = """LOGGING = {
# We use python logging package for logging.
'version': 1,
'disable_existing_loggers': False,
'formatters': {
'verbose': {
'format': '%(levelname)s %(asctime)s %(module)s ' +
'[%(process)d %(thread)d] %(message)s'
},
'simple': {
'format': '%(levelname)s %(asctime)s %(module)s %(lineno)s ' +
'%(message)s'
},
'stats': {
'format': '%(message)s'
},
},
'handlers': {
# Outputs log to console.
'console': {
'level': 'DEBUG',
'class': 'logging.StreamHandler',
'formatter': 'simple'
},
'console_stats': {
'level': 'DEBUG',
'class': 'logging.StreamHandler',
'formatter': 'stats'
},
# Rotates log file when its size reaches 10MB.
'log_file': {
'level': 'DEBUG',
'class': 'logging.handlers.RotatingFileHandler',
'filename': os.path.join('.', 'bgpspeaker.log'),
'maxBytes': '10000000',
'formatter': 'verbose'
},
'stats_file': {
'level': 'DEBUG',
'class': 'logging.handlers.RotatingFileHandler',
'filename': os.path.join('.', 'statistics_bgps.log'),
'maxBytes': '10000000',
'formatter': 'stats'
},
},
# Fine-grained control of logging per instance.
'loggers': {
'bgpspeaker': {
'handlers': ['console', 'log_file'],
'handlers': ['console'],
'level': 'DEBUG',
'propagate': False,
},
'stats': {
'handlers': ['stats_file', 'console_stats'],
'level': 'INFO',
'propagate': False,
'formatter': 'stats',
},
},
# Root loggers.
'root': {
'handlers': ['console', 'log_file'],
'level': 'DEBUG',
'propagate': True,
},
}"""
c << log_conf
with open(os.path.join(self.config_dir, 'bgp_conf.py'), 'w') as f:
LOG.info("[%s's new config]", self.name)
LOG.info(str(c))
f.writelines(str(c))
def create_config(self):
self._create_config_ryu()
self._create_config_ryu_bgp()
def is_running_ryu(self):
results = self.exec_on_ctn('ps ax')
running = False
for line in results.split('\n')[1:]:
if 'ryu-manager' in line:
running = True
return running
def start_ryubgp(self, check_running=True, retry=False):
if check_running:
if self.is_running_ryu():
return True
result = False
if retry:
try_times = 3
else:
try_times = 1
cmd = "ryu-manager --verbose "
cmd += "--config-file %s " % self.SHARED_RYU_CONF
cmd += "--bgp-app-config-file %s " % self.SHARED_BGP_CONF
cmd += "ryu.services.protocols.bgp.application"
for _ in range(try_times):
self.exec_on_ctn(cmd, detach=True)
if self.is_running_ryu():
result = True
break
time.sleep(1)
return result
def stop_ryubgp(self, check_running=True, retry=False):
if check_running:
if not self.is_running_ryu():
return True
result = False
if retry:
try_times = 3
else:
try_times = 1
for _ in range(try_times):
cmd = '/usr/bin/pkill ryu-manager -SIGTERM'
self.exec_on_ctn(cmd)
if not self.is_running_ryu():
result = True
break
time.sleep(1)
return result
def run(self, wait=False, w_time=WAIT_FOR_BOOT):
w_time = super(RyuBGPContainer,
self).run(wait=wait, w_time=self.WAIT_FOR_BOOT)
return w_time
def reload_config(self):
self.stop_ryubgp(retry=True)
self.start_ryubgp(retry=True)