nfv/nfv/nfv-vim/nfv_vim/vim_api.py

168 lines
4.6 KiB
Python
Executable File

#
# Copyright (c) 2015-2016 Wind River Systems, Inc.
#
# SPDX-License-Identifier: Apache-2.0
#
import argparse
from netaddr import IPAddress
import signal
import socket
import sys
from wsgiref import simple_server
from nfv_common import config
from nfv_common import debug
from nfv_common import selobj
from nfv_common import timers
from nfv_common.helpers import coroutine
from nfv_vim.api import Application
PROCESS_TICK_INTERVAL_IN_MS = 500
PROCESS_TICK_MAX_DELAY_IN_MS = 2000
PROCESS_TICK_DELAY_DEBOUNCE_IN_MS = 2000
PROCESS_NOT_RUNNING_FILE = '/var/run/.nfv-vim-api.not_running'
DLOG = debug.debug_get_logger('nfv_vim.api')
stay_on = True
do_reload = False
def get_address_family(ip_string):
"""
Get the family for the given ip address string.
"""
ip_address = IPAddress(ip_string)
if ip_address.version == 6:
return socket.AF_INET6
else:
return socket.AF_INET
def process_signal_handler(signum, frame):
"""
Virtual Infrastructure Manager API - Process Signal Handler
"""
global stay_on, do_reload
if signal.SIGTERM == signum:
stay_on = False
elif signal.SIGINT == signum:
stay_on = False
elif signal.SIGHUP == signum:
do_reload = True
else:
print("Ignoring signal" % signum)
@coroutine
def process_event_handler(wsgi):
"""
Virtual Infrastructure Manager API - Event Handler
"""
while True:
select_obj = (yield)
if select_obj == wsgi:
try:
request, client_address = wsgi.get_request()
if wsgi.verify_request(request, client_address):
try:
wsgi.process_request(request, client_address)
except Exception:
wsgi.handle_error(request, client_address)
wsgi.shutdown_request(request)
except socket.error:
pass
def get_handler_cls():
cls = simple_server.WSGIRequestHandler
# old-style class doesn't support super
class MyHandler(cls, object):
def address_string(self):
# In the future, we could provide a config option to allow
# reverse DNS lookups.
return self.client_address[0]
return MyHandler
def process_initialize():
"""
Virtual Infrastructure Manager API - Initialize
"""
debug.debug_initialize(config.CONF['debug'], 'VIM-API')
selobj.selobj_initialize()
timers.timers_initialize(PROCESS_TICK_INTERVAL_IN_MS,
PROCESS_TICK_MAX_DELAY_IN_MS,
PROCESS_TICK_DELAY_DEBOUNCE_IN_MS)
ip = config.CONF['vim-api']['host']
port = int(config.CONF['vim-api']['port'])
# In order to support IPv6, set the address family before creating the server.
simple_server.WSGIServer.address_family = get_address_family(ip)
wsgi = simple_server.make_server(ip, port, Application(),
handler_class=get_handler_cls())
selobj.selobj_add_read_obj(wsgi, process_event_handler, wsgi)
def process_finalize():
"""
Virtual Infrastructure Manager API - Finalize
"""
timers.timers_finalize()
selobj.selobj_finalize()
debug.debug_finalize()
def process_main():
"""
Virtual Infrastructure Manager API - Main
"""
global do_reload
try:
signal.signal(signal.SIGHUP, process_signal_handler)
signal.signal(signal.SIGINT, process_signal_handler)
signal.signal(signal.SIGTERM, process_signal_handler)
parser = argparse.ArgumentParser()
parser.add_argument('-c', '--config', help='configuration file')
parser.add_argument('-t', '--tox', action="store_true",
help='tox test environment')
args = parser.parse_args()
config.load(args.config)
if args.tox:
# Append the tox root directory to the system path to get
# the config.ini and debug.ini files.
debug_ini = sys.prefix + '/' + config.CONF['debug']['config_file']
config.CONF['debug']['config_file'] = debug_ini
process_initialize()
DLOG.info("Started")
while stay_on:
selobj.selobj_dispatch(PROCESS_TICK_INTERVAL_IN_MS)
timers.timers_schedule()
if do_reload:
debug.debug_reload_config()
do_reload = False
except KeyboardInterrupt:
print("Keyboard Interrupt received.")
except Exception as e:
print(e)
sys.exit(200)
finally:
open(PROCESS_NOT_RUNNING_FILE, 'w').close()
process_finalize()