blob: 27b29f9177889aa288004360d2d36be17b854ee4 [file] [log] [blame]
Zsolt Harasztib71c2a02016-09-12 13:12:07 -07001#!/usr/bin/env python
2#
Zsolt Haraszti3eb27a52017-01-03 21:56:48 -08003# Copyright 2017 the original author or authors.
Zsolt Harasztib71c2a02016-09-12 13:12:07 -07004#
5# Licensed under the Apache License, Version 2.0 (the "License");
6# you may not use this file except in compliance with the License.
7# You may obtain a copy of the License at
8#
9# http://www.apache.org/licenses/LICENSE-2.0
10#
11# Unless required by applicable law or agreed to in writing, software
12# distributed under the License is distributed on an "AS IS" BASIS,
13# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14# See the License for the specific language governing permissions and
15# limitations under the License.
16#
17
Zsolt Harasztiadbb88d2016-09-12 21:24:57 -070018"""Virtual OLT Hardware Abstraction main entry point"""
Zsolt Harasztib71c2a02016-09-12 13:12:07 -070019
20import argparse
Zsolt Harasztib5d72f12017-01-15 20:44:02 -080021import arrow
Zsolt Harasztid7c7c482016-09-13 00:45:38 -070022import os
Zsolt Harasztif2da1d02016-09-13 23:21:35 -070023import time
Zsolt Haraszti023ea7c2016-10-16 19:30:34 -070024
Zsolt Harasztid7c7c482016-09-13 00:45:38 -070025import yaml
Zsolt Haraszti89a27302016-12-08 16:53:06 -080026from simplejson import dumps
Zsolt Harasztie060a7d2016-09-16 11:08:24 -070027from twisted.internet.defer import inlineCallbacks
Zsolt Harasztib5d72f12017-01-15 20:44:02 -080028from twisted.internet.task import LoopingCall
Zsolt Harasztia17f3ec2016-12-08 14:55:49 -080029from zope.interface import implementer
Zsolt Harasztiadbb88d2016-09-12 21:24:57 -070030
Zsolt Haraszti3bfff662016-12-14 23:41:49 -080031from common.event_bus import EventBusClient
32from common.manhole import Manhole
khenaidoocbe30832017-08-25 10:43:27 -040033from common.structlog_setup import setup_logging, update_logging
Zsolt Haraszti023ea7c2016-10-16 19:30:34 -070034from common.utils.dockerhelpers import get_my_containers_name
35from common.utils.nethelpers import get_my_primary_interface, \
Khen Nursimulu441dedd2016-10-05 14:44:26 -070036 get_my_primary_local_ipv4
Zsolt Haraszti7eeb2b32016-11-06 14:04:55 -080037from voltha.adapters.loader import AdapterLoader
Zsolt Harasztid70cd4d2016-11-03 23:23:36 -070038from voltha.coordinator import Coordinator
Zsolt Harasztidafefe12016-11-14 21:29:58 -080039from voltha.core.core import VolthaCore
Ryan Van Gilder5a0ab622017-03-01 16:39:25 -080040from voltha.core.config.config_backend import load_backend
Zsolt Haraszti99509d32016-12-10 16:41:45 -080041from voltha.northbound.diagnostics import Diagnostics
Zsolt Harasztieb435072016-09-23 17:10:49 -070042from voltha.northbound.grpc.grpc_server import VolthaGrpcServer
khenb95fe9a2016-10-05 11:15:25 -070043from voltha.northbound.kafka.kafka_proxy import KafkaProxy, get_kafka_proxy
Zsolt Harasztid70cd4d2016-11-03 23:23:36 -070044from voltha.northbound.rest.health_check import init_rest_service
Zsolt Haraszti66862032016-11-28 14:28:39 -080045from voltha.protos.common_pb2 import LogLevel
Zsolt Harasztia17f3ec2016-12-08 14:55:49 -080046from voltha.registry import registry, IComponent
Zsolt Haraszti89a27302016-12-08 16:53:06 -080047from common.frameio.frameio import FrameIOManager
48
Zsolt Harasztidafefe12016-11-14 21:29:58 -080049VERSION = '0.9.0'
khenb95fe9a2016-10-05 11:15:25 -070050
khenaidoo032d3302017-06-09 14:50:04 -040051
Zsolt Harasztif2da1d02016-09-13 23:21:35 -070052defs = dict(
Zsolt Harasztif2da1d02016-09-13 23:21:35 -070053 config=os.environ.get('CONFIG', './voltha.yml'),
Zsolt Haraszti553826c2016-09-27 10:24:27 -070054 consul=os.environ.get('CONSUL', 'localhost:8500'),
khenaidoo26a8c012017-07-07 18:25:47 -040055 inter_core_subnet=os.environ.get('INTER_CORE_SUBNET', None),
56 pon_subnet=os.environ.get('PON_SUBNET', None),
57 external_host_address=os.environ.get('EXTERNAL_HOST_ADDRESS',
58 get_my_primary_local_ipv4()),
Zsolt Harasztide22bbc2016-09-14 15:27:33 -070059 fluentd=os.environ.get('FLUENTD', None),
Zsolt Haraszti553826c2016-09-27 10:24:27 -070060 grpc_port=os.environ.get('GRPC_PORT', 50055),
61 instance_id=os.environ.get('INSTANCE_ID', os.environ.get('HOSTNAME', '1')),
khenaidoo26a8c012017-07-07 18:25:47 -040062 internal_host_address=os.environ.get('INTERNAL_HOST_ADDRESS',
63 get_my_primary_local_ipv4()),
Zsolt Haraszti553826c2016-09-27 10:24:27 -070064 interface=os.environ.get('INTERFACE', get_my_primary_interface()),
Zsolt Harasztide22bbc2016-09-14 15:27:33 -070065 rest_port=os.environ.get('REST_PORT', 8880),
khenb95fe9a2016-10-05 11:15:25 -070066 kafka=os.environ.get('KAFKA', 'localhost:9092'),
Zsolt Haraszti3bfff662016-12-14 23:41:49 -080067 manhole_port=os.environ.get('MANHOLE_PORT', 12222),
Ryan Van Gilder5a0ab622017-03-01 16:39:25 -080068 backend=os.environ.get('BACKEND', 'none'),
Zsolt Harasztif2da1d02016-09-13 23:21:35 -070069)
Zsolt Harasztib71c2a02016-09-12 13:12:07 -070070
71
72def parse_args():
Zsolt Harasztib71c2a02016-09-12 13:12:07 -070073 parser = argparse.ArgumentParser()
74
Zsolt Haraszti109db832016-09-16 16:32:36 -070075 _help = ('Path to voltha.yml config file (default: %s). '
76 'If relative, it is relative to main.py of voltha.'
77 % defs['config'])
78 parser.add_argument('-c', '--config',
79 dest='config',
80 action='store',
Zsolt Harasztif2da1d02016-09-13 23:21:35 -070081 default=defs['config'],
Zsolt Haraszti109db832016-09-16 16:32:36 -070082 help=_help)
Zsolt Harasztif2da1d02016-09-13 23:21:35 -070083
Zsolt Haraszti109db832016-09-16 16:32:36 -070084 _help = '<hostname>:<port> to consul agent (default: %s)' % defs['consul']
85 parser.add_argument(
86 '-C', '--consul', dest='consul', action='store',
87 default=defs['consul'],
88 help=_help)
Zsolt Harasztif2da1d02016-09-13 23:21:35 -070089
khenaidoo26a8c012017-07-07 18:25:47 -040090
91 _help = ('<inter_core_subnet> is the subnet connecting all the voltha '
92 'instances in a cluster (default: %s)' % defs['inter_core_subnet'])
93 parser.add_argument('-V', '--inter-core-subnet',
94 dest='inter_core_subnet',
95 action='store',
96 default=defs['inter_core_subnet'],
97 help=_help)
98
99 _help = ('<pon subnet> is the subnet connecting the voltha instances'
100 'with the PON network (default: %s)' % defs['pon_subnet'])
101 parser.add_argument('-P', '--pon-subnet',
102 dest='pon_subnet',
103 action='store',
104 default=defs['pon_subnet'],
105 help=_help)
106
Zsolt Haraszti109db832016-09-16 16:32:36 -0700107 _help = ('<hostname> or <ip> at which Voltha is reachable from outside '
108 'the cluster (default: %s)' % defs['external_host_address'])
109 parser.add_argument('-E', '--external-host-address',
110 dest='external_host_address',
111 action='store',
Zsolt Harasztif2da1d02016-09-13 23:21:35 -0700112 default=defs['external_host_address'],
Zsolt Haraszti109db832016-09-16 16:32:36 -0700113 help=_help)
Zsolt Harasztif2da1d02016-09-13 23:21:35 -0700114
Zsolt Haraszti553826c2016-09-27 10:24:27 -0700115 _help = ('port number of the GRPC service exposed by voltha (default: %s)'
116 % defs['grpc_port'])
117 parser.add_argument('-g', '--grpc-port',
118 dest='grpc_port',
119 action='store',
120 default=defs['grpc_port'],
121 help=_help)
Khen Nursimulu441dedd2016-10-05 14:44:26 -0700122
Zsolt Haraszti109db832016-09-16 16:32:36 -0700123 _help = ('<hostname>:<port> to fluentd server (default: %s). (If not '
124 'specified (None), the address from the config file is used'
125 % defs['fluentd'])
126 parser.add_argument('-F', '--fluentd',
127 dest='fluentd',
128 action='store',
Zsolt Harasztif2da1d02016-09-13 23:21:35 -0700129 default=defs['fluentd'],
Zsolt Haraszti109db832016-09-16 16:32:36 -0700130 help=_help)
Zsolt Harasztif2da1d02016-09-13 23:21:35 -0700131
Zsolt Haraszti109db832016-09-16 16:32:36 -0700132 _help = ('<hostname> or <ip> at which Voltha is reachable from inside the'
133 'cluster (default: %s)' % defs['internal_host_address'])
134 parser.add_argument('-H', '--internal-host-address',
135 dest='internal_host_address',
136 action='store',
Zsolt Harasztif2da1d02016-09-13 23:21:35 -0700137 default=defs['internal_host_address'],
Zsolt Haraszti109db832016-09-16 16:32:36 -0700138 help=_help)
Zsolt Harasztif2da1d02016-09-13 23:21:35 -0700139
Zsolt Haraszti109db832016-09-16 16:32:36 -0700140 _help = ('unique string id of this voltha instance (default: %s)'
Zsolt Haraszti86be6f12016-09-27 09:56:49 -0700141 % defs['instance_id'])
Zsolt Haraszti109db832016-09-16 16:32:36 -0700142 parser.add_argument('-i', '--instance-id',
143 dest='instance_id',
144 action='store',
Zsolt Harasztif2da1d02016-09-13 23:21:35 -0700145 default=defs['instance_id'],
Zsolt Haraszti109db832016-09-16 16:32:36 -0700146 help=_help)
Zsolt Harasztif2da1d02016-09-13 23:21:35 -0700147
khenaidooccc42252017-07-06 23:00:49 -0400148 _help = 'ETH interface to recieve (default: %s)' % defs['interface']
Zsolt Haraszti109db832016-09-16 16:32:36 -0700149 parser.add_argument('-I', '--interface',
150 dest='interface',
151 action='store',
Zsolt Harasztif2da1d02016-09-13 23:21:35 -0700152 default=defs['interface'],
Zsolt Haraszti109db832016-09-16 16:32:36 -0700153 help=_help)
Zsolt Harasztif2da1d02016-09-13 23:21:35 -0700154
Zsolt Haraszti3bfff662016-12-14 23:41:49 -0800155 _help = 'open ssh manhole at given port'
156 parser.add_argument('-m', '--manhole-port',
157 dest='manhole_port',
158 action='store',
159 type=int,
160 default=None,
161 help=_help)
162
Zsolt Haraszti109db832016-09-16 16:32:36 -0700163 _help = 'omit startup banner log lines'
164 parser.add_argument('-n', '--no-banner',
165 dest='no_banner',
166 action='store_true',
167 default=False,
168 help=_help)
Zsolt Harasztif2da1d02016-09-13 23:21:35 -0700169
Zsolt Haraszti109db832016-09-16 16:32:36 -0700170 _help = 'do not emit periodic heartbeat log messages'
171 parser.add_argument('-N', '--no-heartbeat',
172 dest='no_heartbeat',
173 action='store_true',
174 default=False,
175 help=_help)
Zsolt Harasztif2da1d02016-09-13 23:21:35 -0700176
Zsolt Haraszti109db832016-09-16 16:32:36 -0700177 _help = ('port number for the rest service (default: %d)'
178 % defs['rest_port'])
179 parser.add_argument('-R', '--rest-port',
180 dest='rest_port',
181 action='store',
182 type=int,
Zsolt Harasztide22bbc2016-09-14 15:27:33 -0700183 default=defs['rest_port'],
Zsolt Haraszti109db832016-09-16 16:32:36 -0700184 help=_help)
Zsolt Harasztide22bbc2016-09-14 15:27:33 -0700185
Zsolt Haraszti109db832016-09-16 16:32:36 -0700186 _help = "suppress debug and info logs"
187 parser.add_argument('-q', '--quiet',
188 dest='quiet',
Zsolt Haraszti1420def2016-09-18 00:07:31 -0700189 action='count',
Zsolt Haraszti109db832016-09-16 16:32:36 -0700190 help=_help)
Zsolt Harasztiadbb88d2016-09-12 21:24:57 -0700191
Zsolt Haraszti109db832016-09-16 16:32:36 -0700192 _help = 'enable verbose logging'
193 parser.add_argument('-v', '--verbose',
194 dest='verbose',
Zsolt Haraszti1420def2016-09-18 00:07:31 -0700195 action='count',
Zsolt Haraszti109db832016-09-16 16:32:36 -0700196 help=_help)
Zsolt Harasztiadbb88d2016-09-12 21:24:57 -0700197
Zsolt Haraszti109db832016-09-16 16:32:36 -0700198 _help = ('use docker container name as voltha instance id'
199 ' (overrides -i/--instance-id option)')
200 parser.add_argument('--instance-id-is-container-name',
201 dest='instance_id_is_container_name',
202 action='store_true',
203 default=False,
204 help=_help)
Zsolt Harasztie060a7d2016-09-16 11:08:24 -0700205
khenb95fe9a2016-10-05 11:15:25 -0700206 _help = ('<hostname>:<port> of the kafka broker (default: %s). (If not '
207 'specified (None), the address from the config file is used'
208 % defs['kafka'])
209 parser.add_argument('-K', '--kafka',
210 dest='kafka',
211 action='store',
212 default=defs['kafka'],
213 help=_help)
214
Ryan Van Gilder5a0ab622017-03-01 16:39:25 -0800215 _help = 'backend to use for config persitence'
216 parser.add_argument('-b', '--backend',
217 default=defs['backend'],
218 choices=['none', 'consul'],
219 help=_help)
220
Zsolt Harasztie060a7d2016-09-16 11:08:24 -0700221 args = parser.parse_args()
222
223 # post-processing
224
225 if args.instance_id_is_container_name:
226 args.instance_id = get_my_containers_name()
227
khenaidoo26a8c012017-07-07 18:25:47 -0400228 """
229 The container external, internal IP and PON interface needs to be
230 set based on the subnet data. At this time the internal IP is not used.
231 The external IP is used for inter-core communications. If the subnets are
232 set then they take precedence over the other relevant arguments (
233 external and internal host as well as interface
234 """
235 if args.inter_core_subnet:
236 m_ip = get_my_primary_local_ipv4(inter_core_subnet=args.inter_core_subnet)
khenaidooccc42252017-07-06 23:00:49 -0400237 args.external_host_address = m_ip
khenaidooccc42252017-07-06 23:00:49 -0400238 args.internal_host_address = m_ip
239
khenaidoo26a8c012017-07-07 18:25:47 -0400240 if args.pon_subnet:
241 args.interface = get_my_primary_interface(args.pon_subnet)
242
Zsolt Harasztie060a7d2016-09-16 11:08:24 -0700243 return args
Zsolt Harasztib71c2a02016-09-12 13:12:07 -0700244
245
Zsolt Harasztid7c7c482016-09-13 00:45:38 -0700246def load_config(args):
247 path = args.config
248 if path.startswith('.'):
249 dir = os.path.dirname(os.path.abspath(__file__))
250 path = os.path.join(dir, path)
251 path = os.path.abspath(path)
252 with open(path) as fd:
253 config = yaml.load(fd)
254 return config
255
256
Zsolt Harasztie060a7d2016-09-16 11:08:24 -0700257def print_banner(log):
Zsolt Harasztib71c2a02016-09-12 13:12:07 -0700258 log.info(' _ ______ __ ________ _____ ')
259 log.info('| | / / __ \/ / /_ __/ / / / |')
260 log.info('| | / / / / / / / / / /_/ / /| |')
261 log.info('| |/ / /_/ / /___/ / / __ / ___ |')
262 log.info('|___/\____/_____/_/ /_/ /_/_/ |_|')
Zsolt Haraszti59b7a882016-09-12 14:42:59 -0700263 log.info('(to stop: press Ctrl-C)')
Zsolt Harasztib71c2a02016-09-12 13:12:07 -0700264
265
Zsolt Harasztia17f3ec2016-12-08 14:55:49 -0800266@implementer(IComponent)
Zsolt Harasztie060a7d2016-09-16 11:08:24 -0700267class Main(object):
Zsolt Harasztia17f3ec2016-12-08 14:55:49 -0800268
Zsolt Harasztie060a7d2016-09-16 11:08:24 -0700269 def __init__(self):
Zsolt Haraszti1420def2016-09-18 00:07:31 -0700270
Zsolt Harasztie060a7d2016-09-16 11:08:24 -0700271 self.args = args = parse_args()
272 self.config = load_config(args)
Zsolt Haraszti1420def2016-09-18 00:07:31 -0700273
274 verbosity_adjust = (args.verbose or 0) - (args.quiet or 0)
Zsolt Haraszti109db832016-09-16 16:32:36 -0700275 self.log = setup_logging(self.config.get('logging', {}),
276 args.instance_id,
Zsolt Haraszti1420def2016-09-18 00:07:31 -0700277 verbosity_adjust=verbosity_adjust,
Zsolt Haraszti109db832016-09-16 16:32:36 -0700278 fluentd=args.fluentd)
Zsolt Harasztif2da1d02016-09-13 23:21:35 -0700279
Rouzbahan Rashidi-Tabrizi1c3eba82016-10-27 21:47:18 -0400280 # configurable variables from voltha.yml file
281 #self.configurable_vars = self.config.get('Constants', {})
282
Zsolt Harasztie060a7d2016-09-16 11:08:24 -0700283 if not args.no_banner:
284 print_banner(self.log)
Zsolt Harasztib71c2a02016-09-12 13:12:07 -0700285
khenaidoo032d3302017-06-09 14:50:04 -0400286 # Create a unique instnce id using the passed-in instanceid and
287 # UTC timestamp
288 current_time = arrow.utcnow().timestamp
289 self.instance_id = self.args.instance_id + '_' + str(current_time)
290
291 # Every voltha instance is given a core_storage id where the
292 # instance data is stored
293 self.core_store_id = None
294
khenb95fe9a2016-10-05 11:15:25 -0700295 self.startup_components()
296
Zsolt Harasztie060a7d2016-09-16 11:08:24 -0700297 if not args.no_heartbeat:
298 self.start_heartbeat()
khenaidoo032d3302017-06-09 14:50:04 -0400299 self.start_kafka_heartbeat(self.instance_id)
Zsolt Harasztib71c2a02016-09-12 13:12:07 -0700300
Zsolt Haraszti3bfff662016-12-14 23:41:49 -0800301 self.manhole = None
302
Zsolt Harasztie060a7d2016-09-16 11:08:24 -0700303 def start(self):
304 self.start_reactor() # will not return except Keyboard interrupt
Zsolt Harasztif2da1d02016-09-13 23:21:35 -0700305
Zsolt Harasztia17f3ec2016-12-08 14:55:49 -0800306 def stop(self):
307 pass
308
309 def get_args(self):
310 """Allow access to command line args"""
311 return self.args
312
313 def get_config(self):
314 """Allow access to content of config file"""
315 return self.config
316
Zsolt Haraszti7eeb2b32016-11-06 14:04:55 -0800317 @inlineCallbacks
Zsolt Harasztie060a7d2016-09-16 11:08:24 -0700318 def startup_components(self):
Khen Nursimulu3c74d3b2016-11-08 15:14:01 -0800319 try:
khenaidooccc42252017-07-06 23:00:49 -0400320 self.log.info('starting-internal-components',
321 internal_host=self.args.internal_host_address,
khenaidoo26a8c012017-07-07 18:25:47 -0400322 external_host=self.args.external_host_address,
323 interface=self.args.interface,
324 consul=self.args.consul)
Zsolt Harasztidafefe12016-11-14 21:29:58 -0800325
Zsolt Harasztia17f3ec2016-12-08 14:55:49 -0800326 registry.register('main', self)
327
Zsolt Haraszti66862032016-11-28 14:28:39 -0800328 yield registry.register(
329 'coordinator',
330 Coordinator(
331 internal_host_address=self.args.internal_host_address,
332 external_host_address=self.args.external_host_address,
333 rest_port=self.args.rest_port,
khenaidoo032d3302017-06-09 14:50:04 -0400334 instance_id=self.instance_id,
Zsolt Haraszti66862032016-11-28 14:28:39 -0800335 config=self.config,
336 consul=self.args.consul)
337 ).start()
Zsolt Harasztidafefe12016-11-14 21:29:58 -0800338
khenaidoo032d3302017-06-09 14:50:04 -0400339 self.log.info('waiting-for-config-assignment')
340
341 # Wait until we get a config id before we proceed
342 self.core_store_id, store_prefix = \
343 yield registry('coordinator').get_core_store_id_and_prefix()
344
345 self.log.info('store-id', core_store_id=self.core_store_id)
Zsolt Harasztieb435072016-09-23 17:10:49 -0700346
khenaidoocbe30832017-08-25 10:43:27 -0400347 # Update the logger to output the vcore id.
348 self.log = update_logging(instance_id=self.instance_id, vcore_id=self.core_store_id)
349
Zsolt Haraszti66862032016-11-28 14:28:39 -0800350 yield registry.register(
351 'grpc_server',
352 VolthaGrpcServer(self.args.grpc_port)
353 ).start()
Zsolt Harasztieb435072016-09-23 17:10:49 -0700354
Zsolt Haraszti66862032016-11-28 14:28:39 -0800355 yield registry.register(
khenaidoo032d3302017-06-09 14:50:04 -0400356 'core',
357 VolthaCore(
358 instance_id=self.instance_id,
359 core_store_id = self.core_store_id,
khenaidoo08d48d22017-06-29 19:42:49 -0400360 grpc_port=self.args.grpc_port,
khenaidoo032d3302017-06-09 14:50:04 -0400361 version=VERSION,
362 log_level=LogLevel.INFO
363 )
364 ).start(config_backend=load_backend(store_id=self.core_store_id,
365 store_prefix=store_prefix,
366 args=self.args))
367
368 init_rest_service(self.args.rest_port)
369
370 yield registry.register(
Zsolt Haraszti66862032016-11-28 14:28:39 -0800371 'kafka_proxy',
Zsolt Haraszti99509d32016-12-10 16:41:45 -0800372 KafkaProxy(
373 self.args.consul,
374 self.args.kafka,
375 config=self.config.get('kafka-proxy', {})
376 )
Zsolt Haraszti66862032016-11-28 14:28:39 -0800377 ).start()
378
379 yield registry.register(
Zsolt Haraszti89a27302016-12-08 16:53:06 -0800380 'frameio',
381 FrameIOManager()
382 ).start()
383
384 yield registry.register(
Zsolt Haraszti66862032016-11-28 14:28:39 -0800385 'adapter_loader',
386 AdapterLoader(config=self.config.get('adapter_loader', {}))
387 ).start()
khenb95fe9a2016-10-05 11:15:25 -0700388
Zsolt Haraszti99509d32016-12-10 16:41:45 -0800389 yield registry.register(
390 'diag',
391 Diagnostics(config=self.config.get('diagnostics', {}))
392 ).start()
393
Zsolt Haraszti3bfff662016-12-14 23:41:49 -0800394 if self.args.manhole_port is not None:
395 self.start_manhole(self.args.manhole_port)
396
khenaidoo032d3302017-06-09 14:50:04 -0400397 # Now that all components are loaded, in the scenario where this
398 # voltha instance is picking up an existing set of data (from a
399 # voltha instance that dies/stopped) then we need to setup this
400 # instance from where the previous one left
401
402 yield registry('core').reconcile_data()
403
khenaidoocbe30832017-08-25 10:43:27 -0400404 # Now that the data is in memory and the reconcile process
405 # within the core has completed (the reconciliation may still be
406 # in progress with the adapters) we expose the NBI of voltha core
407 yield registry('core').register_grpc_service()
408
Khen Nursimulu3c74d3b2016-11-08 15:14:01 -0800409 self.log.info('started-internal-services')
410
411 except Exception as e:
khenaidoo032d3302017-06-09 14:50:04 -0400412 self.log.exception('Failure-to-start-all-components', e=e)
Khen Nursimulu3c74d3b2016-11-08 15:14:01 -0800413
Zsolt Haraszti3bfff662016-12-14 23:41:49 -0800414 def start_manhole(self, port):
415 self.manhole = Manhole(
416 port,
417 pws=dict(admin='adminpw'),
418 eventbus = EventBusClient(),
419 **registry.components
420 )
421
Zsolt Harasztie060a7d2016-09-16 11:08:24 -0700422 @inlineCallbacks
423 def shutdown_components(self):
424 """Execute before the reactor is shut down"""
425 self.log.info('exiting-on-keyboard-interrupt')
Zsolt Harasztidafefe12016-11-14 21:29:58 -0800426 for component in reversed(registry.iterate()):
427 yield component.stop()
Zsolt Harasztif2da1d02016-09-13 23:21:35 -0700428
Zsolt Haraszti3300f742017-01-09 01:14:20 -0800429 import threading
430 self.log.info('THREADS:')
431 main_thread = threading.current_thread()
432 for t in threading.enumerate():
433 if t is main_thread:
434 continue
435 if not t.isDaemon():
436 continue
437 self.log.info('joining thread {} {}'.format(
438 t.getName(), "daemon" if t.isDaemon() else "not-daemon"))
439 t.join()
440
Zsolt Harasztie060a7d2016-09-16 11:08:24 -0700441 def start_reactor(self):
442 from twisted.internet import reactor
Zsolt Haraszti109db832016-09-16 16:32:36 -0700443 reactor.callWhenRunning(
444 lambda: self.log.info('twisted-reactor-started'))
445 reactor.addSystemEventTrigger('before', 'shutdown',
446 self.shutdown_components)
Zsolt Harasztie060a7d2016-09-16 11:08:24 -0700447 reactor.run()
Zsolt Harasztif2da1d02016-09-13 23:21:35 -0700448
Zsolt Harasztie060a7d2016-09-16 11:08:24 -0700449 def start_heartbeat(self):
Zsolt Harasztif2da1d02016-09-13 23:21:35 -0700450
Zsolt Harasztie060a7d2016-09-16 11:08:24 -0700451 t0 = time.time()
452 t0s = time.ctime(t0)
Zsolt Harasztif2da1d02016-09-13 23:21:35 -0700453
Zsolt Harasztie060a7d2016-09-16 11:08:24 -0700454 def heartbeat():
455 self.log.debug(status='up', since=t0s, uptime=time.time() - t0)
Zsolt Harasztif2da1d02016-09-13 23:21:35 -0700456
Zsolt Harasztie060a7d2016-09-16 11:08:24 -0700457 lc = LoopingCall(heartbeat)
458 lc.start(10)
Zsolt Harasztib71c2a02016-09-12 13:12:07 -0700459
khenb95fe9a2016-10-05 11:15:25 -0700460 # Temporary function to send a heartbeat message to the external kafka
461 # broker
Zsolt Haraszti89a27302016-12-08 16:53:06 -0800462 def start_kafka_heartbeat(self, instance_id):
khenb95fe9a2016-10-05 11:15:25 -0700463 # For heartbeat we will send a message to a specific "voltha-heartbeat"
464 # topic. The message is a protocol buf
465 # message
Zsolt Harasztib5d72f12017-01-15 20:44:02 -0800466 message = dict(
Zsolt Haraszti89a27302016-12-08 16:53:06 -0800467 type='heartbeat',
468 voltha_instance=instance_id,
469 ip=get_my_primary_local_ipv4()
Zsolt Harasztib5d72f12017-01-15 20:44:02 -0800470 )
471 topic = "voltha.heartbeat"
khenb95fe9a2016-10-05 11:15:25 -0700472
Zsolt Harasztib5d72f12017-01-15 20:44:02 -0800473 def send_msg():
Rouzbahan Rashidi-Tabrizi380dcb32017-03-23 18:01:02 -0400474 try:
475 kafka_proxy = get_kafka_proxy()
476 if kafka_proxy and not kafka_proxy.is_faulty():
477 self.log.debug('kafka-proxy-available')
478 message['ts'] = arrow.utcnow().timestamp
479 self.log.debug('start-kafka-heartbeat')
480 kafka_proxy.send_message(topic, dumps(message))
481 else:
482 self.log.error('kafka-proxy-unavailable')
483 except Exception, e:
484 self.log.exception('failed-sending-message-heartbeat', e=e)
Zsolt Harasztib5d72f12017-01-15 20:44:02 -0800485
Rouzbahan Rashidi-Tabrizi380dcb32017-03-23 18:01:02 -0400486 try:
Zsolt Harasztib5d72f12017-01-15 20:44:02 -0800487 lc = LoopingCall(send_msg)
Khen Nursimulu3c74d3b2016-11-08 15:14:01 -0800488 lc.start(10)
Rouzbahan Rashidi-Tabrizi380dcb32017-03-23 18:01:02 -0400489 except Exception, e:
490 self.log.exception('failed-kafka-heartbeat', e=e)
Khen Nursimulu441dedd2016-10-05 14:44:26 -0700491
Zsolt Haraszti89a27302016-12-08 16:53:06 -0800492
Zsolt Harasztib71c2a02016-09-12 13:12:07 -0700493if __name__ == '__main__':
Zsolt Harasztie060a7d2016-09-16 11:08:24 -0700494 Main().start()