1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
|
#!/usr/bin/env python3
# -*- coding: utf-8 -*-
#
# Copyright (c) 2017 Cisco and/or its affiliates.
#
# 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.
#
import asyncio
import json
import logging
import os
import resource as ulimit
import sys
from netmodel.model.query import Query
from netmodel.model.query import ACTION_SELECT, ACTION_INSERT
from netmodel.model.query import ACTION_UPDATE, ACTION_SUBSCRIBE
from netmodel.network.interface import InterfaceState
from netmodel.util.singleton import Singleton
from vicn.core.exception import NotConfigured
from vicn.core.resource_mgr import ResourceManager
from vicn.resource.node import Node
DEFAULT_SETTINGS = {
'network': '192.168.0.0/16',
'bridge_name': 'br0',
'mac_address_base': '0x00163e000000',
'websocket_port': 9999
}
log = logging.getLogger(__name__)
class Event_ts(asyncio.Event):
def set(self):
self._loop.call_soon_threadsafe(super().set)
#------------------------------------------------------------------------------
class API(metaclass = Singleton):
def terminate(self):
# XXX not valid if nothing has been initialized
ResourceManager().terminate()
os._exit(0)
def parse_topology_file(self, topology_fn, resources, settings):
log.info("Parsing topology file %(topology_fn)s" % locals())
try:
topology_fd = open(topology_fn, 'r')
except IOError:
log.error("Topology file '%(topology_fn)s not found" % locals())
sys.exit(1)
try:
topology = json.loads(topology_fd.read())
# SETTING
settings.update(topology.get('settings', dict()))
# NODES
resources.extend(topology.get('resources', list()))
except SyntaxError:
log.error("Error reading topology file '%s'" % (topology_fn,))
sys.exit(1)
log.debug("Done parsing topology file %(topology_fn)s" % locals())
def configure(self, scenario_list):
log.info("Parsing configuration file", extra={'category': 'blue'})
resources = list()
settings = DEFAULT_SETTINGS
for scenario in scenario_list:
self.parse_topology_file(scenario, resources, settings)
# VICN process-related initializations
nofile = settings.get('ulimit-n', None)
if nofile is not None and nofile > 0:
if nofile < 1024:
log.error('Too few allowed open files for the process')
os._exit(1)
log.info('Setting open file descriptor limit to {}'.format(
nofile))
ulimit.setrlimit(
ulimit.RLIMIT_NOFILE,
(nofile, nofile))
base = os.path.dirname(scenario_list[-1])
base = os.path.abspath(base)
ResourceManager(base = base, settings = settings)
for resource in resources:
try:
ResourceManager().create_from_dict(**resource)
except Exception as e:
import traceback; traceback.print_exc()
log.error("Could not create resource '%r': %r" % \
(resource, e,))
os._exit(1)
self._configured = True
def setup(self, commit = False):
if not self._configured:
raise NotConfigured
ResourceManager().setup(commit)
def teardown(self):
ResourceManager().teardown()
def open_terminal(self, node_name):
node = ResourceManager().by_name(node_name)
assert isinstance(node, Node)
node.open_terminal()
|