1 # Copyright (C) 2016 Nippon Telegraph and Telephone Corporation.
3 # Licensed under the Apache License, Version 2.0 (the "License");
4 # you may not use this file except in compliance with the License.
5 # You may obtain a copy of the License at
7 # http://www.apache.org/licenses/LICENSE-2.0
9 # Unless required by applicable law or agreed to in writing, software
10 # distributed under the License is distributed on an "AS IS" BASIS,
11 # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
13 # See the License for the specific language governing permissions and
14 # limitations under the License.
16 from __future__ import absolute_import
22 from . import docker_base as base
24 LOG = logging.getLogger(__name__)
27 class RyuBGPContainer(base.BGPContainer):
30 SHARED_VOLUME = '/etc/ryu'
32 def __init__(self, name, asn, router_id, ctn_image_name):
33 super(RyuBGPContainer, self).__init__(name, asn, router_id,
35 self.RYU_CONF = os.path.join(self.config_dir, 'ryu.conf')
36 self.SHARED_RYU_CONF = os.path.join(self.SHARED_VOLUME, 'ryu.conf')
37 self.SHARED_BGP_CONF = os.path.join(self.SHARED_VOLUME, 'bgp_conf.py')
38 self.shared_volumes.append((self.config_dir, self.SHARED_VOLUME))
40 def _create_config_ryu(self):
44 c << 'log_file=/etc/ryu/manager.log'
45 with open(self.RYU_CONF, 'w') as f:
46 LOG.info("[%s's new config]" % self.name)
50 def _create_config_ryu_bgp(self):
55 c << " 'local_as': %s," % str(self.asn)
56 c << " 'router_id': '%s'," % self.router_id
57 c << " 'neighbors': ["
59 for peer, info in self.peers.items():
60 n_addr = info['neigh_addr'].split('/')[0]
61 c << " 'address': '%s'," % n_addr
62 c << " 'remote_as': %s," % str(peer.asn)
63 c << " 'enable_ipv4': True,"
64 c << " 'enable_ipv6': True,"
65 c << " 'enable_vpnv4': True,"
66 c << " 'enable_vpnv6': True,"
70 for route in self.routes.values():
72 c << " 'prefix': '%s'," % route['prefix']
76 log_conf = """LOGGING = {
78 # We use python logging package for logging.
80 'disable_existing_loggers': False,
84 'format': '%(levelname)s %(asctime)s %(module)s ' +
85 '[%(process)d %(thread)d] %(message)s'
88 'format': '%(levelname)s %(asctime)s %(module)s %(lineno)s ' +
92 'format': '%(message)s'
97 # Outputs log to console.
100 'class': 'logging.StreamHandler',
101 'formatter': 'simple'
105 'class': 'logging.StreamHandler',
108 # Rotates log file when its size reaches 10MB.
111 'class': 'logging.handlers.RotatingFileHandler',
112 'filename': os.path.join('.', 'bgpspeaker.log'),
113 'maxBytes': '10000000',
114 'formatter': 'verbose'
118 'class': 'logging.handlers.RotatingFileHandler',
119 'filename': os.path.join('.', 'statistics_bgps.log'),
120 'maxBytes': '10000000',
125 # Fine-grained control of logging per instance.
128 'handlers': ['console', 'log_file'],
129 'handlers': ['console'],
134 'handlers': ['stats_file', 'console_stats'],
137 'formatter': 'stats',
143 'handlers': ['console', 'log_file'],
149 with open(os.path.join(self.config_dir, 'bgp_conf.py'), 'w') as f:
150 LOG.info("[%s's new config]", self.name)
154 def create_config(self):
155 self._create_config_ryu()
156 self._create_config_ryu_bgp()
158 def is_running_ryu(self):
159 results = self.exec_on_ctn('ps ax')
161 for line in results.split('\n')[1:]:
162 if 'ryu-manager' in line:
166 def start_ryubgp(self, check_running=True, retry=False):
168 if self.is_running_ryu():
175 cmd = "ryu-manager --verbose "
176 cmd += "--config-file %s " % self.SHARED_RYU_CONF
177 cmd += "--bgp-app-config-file %s " % self.SHARED_BGP_CONF
178 cmd += "ryu.services.protocols.bgp.application"
179 for _ in range(try_times):
180 self.exec_on_ctn(cmd, detach=True)
181 if self.is_running_ryu():
187 def stop_ryubgp(self, check_running=True, retry=False):
189 if not self.is_running_ryu():
196 for _ in range(try_times):
197 cmd = '/usr/bin/pkill ryu-manager -SIGTERM'
198 self.exec_on_ctn(cmd)
199 if not self.is_running_ryu():
205 def run(self, wait=False, w_time=WAIT_FOR_BOOT):
206 w_time = super(RyuBGPContainer,
207 self).run(wait=wait, w_time=self.WAIT_FOR_BOOT)
210 def reload_config(self):
211 self.stop_ryubgp(retry=True)
212 self.start_ryubgp(retry=True)