aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorMarcel Enguehard <mengueha+fdio@cisco.com>2017-10-09 08:44:59 +0200
committerMarcel Enguehard <mengueha+fdio@cisco.com>2017-10-09 08:55:46 +0200
commit5f8867a3454164ad20ae427dc9d2c7d65ea00a90 (patch)
treec8ff40fb147a76af2baa77790ba8a6ac968e51b4
parentaf2dd545d04cfca7e7ec066035abf78c3d541915 (diff)
Several fixes related to async_set, ip addressing, and memif interfaces for VPP
Change-Id: I26b7928751f41ea66ba47bb1becac33cf5195915 Signed-off-by: Marcel Enguehard <mengueha+fdio@cisco.com>
-rw-r--r--examples/tutorial/tutorial06-acm-icn17-vpp.json141
-rw-r--r--examples/tutorial/tutorial06-acm-icn17.json115
-rw-r--r--netmodel/interfaces/process/__init__.py2
-rw-r--r--vicn/core/resource.py9
-rw-r--r--vicn/core/resource_mgr.py12
-rw-r--r--vicn/resource/icn/central.py6
-rw-r--r--vicn/resource/icn/cicn.py7
-rw-r--r--vicn/resource/ip/central.py4
-rw-r--r--vicn/resource/lxd/lxc_container.py1
-rw-r--r--vicn/resource/vpp/interface.py74
-rw-r--r--vicn/resource/vpp/memif_link.py2
-rw-r--r--vicn/resource/vpp/scripts.py2
-rw-r--r--vicn/resource/vpp/vpp.py5
-rw-r--r--vicn/resource/vpp/vpp_commands.py3
-rw-r--r--www/img/smartphone.png17
15 files changed, 365 insertions, 35 deletions
diff --git a/examples/tutorial/tutorial06-acm-icn17-vpp.json b/examples/tutorial/tutorial06-acm-icn17-vpp.json
new file mode 100644
index 00000000..406ac343
--- /dev/null
+++ b/examples/tutorial/tutorial06-acm-icn17-vpp.json
@@ -0,0 +1,141 @@
+{
+ "resources": [
+ {
+ "type": "Group",
+ "name": "virtual"
+ },
+ {
+ "type": "Physical",
+ "name": "server",
+ "hostname": "localhost"
+ },
+ {
+ "type": "LxcImage",
+ "name": "cicn-image",
+ "node": "server",
+ "image": "ubuntu1604-cicnsuite-rc4"
+ },
+ {
+ "type": "GUI",
+ "port": 8000,
+ "groups": ["virtual"]
+ },
+ {
+ "type" : "LxcContainer",
+ "image": "cicn-image",
+ "name" : "cons",
+ "groups": [ "virtual" ],
+ "category": "user",
+ "node" : "server"
+ },
+ {
+ "type" : "LxcContainer",
+ "image": "cicn-image",
+ "name" : "prod",
+ "groups": [ "virtual" ],
+ "category": "video-server",
+ "node" : "server"
+ },
+ {
+ "type" : "LxcContainer",
+ "image": "cicn-image",
+ "name" : "core1",
+ "groups": [ "virtual" ],
+ "category": "icn-router-vpp",
+ "node" : "server"
+ },
+ {
+ "type" : "LxcContainer",
+ "image": "cicn-image",
+ "name" : "core2",
+ "groups": [ "virtual" ],
+ "category": "icn-router-vpp",
+ "node" : "server"
+ },
+ {
+ "type": "DpdkDevice",
+ "name": "core1-dpdk1",
+ "mac_address": "08:00:27:5c:5b:f1",
+ "node": "core1",
+ "device_name": "GigabitEthernet0/9/0",
+ "pci_address": "0000:00:09.0"
+ },
+ {
+ "type": "DpdkDevice",
+ "name": "core2-dpdk1",
+ "mac_address": "08:00:27:8c:e3:49",
+ "node": "core2",
+ "device_name": "GigabitEthernet0/a/0",
+ "pci_address": "0000:00:0a.0"
+ },
+ {
+ "type": "VPP",
+ "node": "core1",
+ "name": "vpp-core1"
+ },
+ {
+ "type": "VPP",
+ "node": "core2",
+ "name": "vpp-core2"
+ },
+ {
+ "type": "Link",
+ "src_node": "cons",
+ "dst_node": "core1",
+ "groups": [ "virtual" ]
+ },
+ {
+ "type": "PhyLink",
+ "src": "core1-dpdk1",
+ "dst": "core2-dpdk1",
+ "groups": [ "virtual" ]
+ },
+ {
+ "type": "Link",
+ "src_node": "core2",
+ "dst_node": "prod",
+ "groups": [ "virtual" ]
+ },
+ {
+ "type": "CentralIP",
+ "ip4_data_prefix": "192.168.42.0/24",
+ "ip6_data_prefix": "9002::/16",
+ "ip_routing_strategy": "spt",
+ "groups": [
+ "virtual"
+ ]
+ },
+ {
+ "type": "MetisForwarder",
+ "cache_size": 0,
+ "node": "cons"
+ },
+ {
+ "type": "CICNForwarder",
+ "node": "core1",
+ "name": "vpp_core1"
+ },
+ {
+ "type": "CICNForwarder",
+ "node": "core2",
+ "name": "vpp_core2"
+ },
+ {
+ "type": "MetisForwarder",
+ "cache_size": 0,
+ "node": "prod"
+ },
+ {
+ "type": "WebServer",
+ "prefixes": [
+ "/webserver"
+ ],
+ "node": "prod"
+ },
+ {
+ "type": "CentralICN",
+ "groups": [ "virtual" ],
+ "face_protocol": "udp4"
+ }
+ ]
+}
diff --git a/examples/tutorial/tutorial06-acm-icn17.json b/examples/tutorial/tutorial06-acm-icn17.json
new file mode 100644
index 00000000..e65e44d7
--- /dev/null
+++ b/examples/tutorial/tutorial06-acm-icn17.json
@@ -0,0 +1,115 @@
+{
+ "resources": [
+ {
+ "type": "Group",
+ "name": "virtual"
+ },
+ {
+ "type": "Physical",
+ "name": "server",
+ "hostname": "localhost"
+ },
+ {
+ "type": "LxcImage",
+ "name": "cicn-image",
+ "node": "server",
+ "image": "ubuntu1604-cicnsuite-rc4"
+ },
+ {
+ "type": "GUI",
+ "port": 8000,
+ "groups": ["virtual"]
+ },
+ {
+ "type" : "LxcContainer",
+ "image": "cicn-image",
+ "name" : "cons",
+ "groups": [ "virtual" ],
+ "category": "user",
+ "node" : "server"
+ },
+ {
+ "type" : "LxcContainer",
+ "image": "cicn-image",
+ "name" : "prod",
+ "groups": [ "virtual" ],
+ "category": "video-server",
+ "node" : "server"
+ },
+ {
+ "type" : "LxcContainer",
+ "image": "cicn-image",
+ "name" : "core1",
+ "groups": [ "virtual" ],
+ "category": "icn-router",
+ "node" : "server"
+ },
+ {
+ "type" : "LxcContainer",
+ "image": "cicn-image",
+ "name" : "core2",
+ "groups": [ "virtual" ],
+ "category": "icn-router",
+ "node" : "server"
+ },
+ {
+ "type": "Link",
+ "src_node": "cons",
+ "dst_node": "core1",
+ "groups": [ "virtual" ]
+ },
+ {
+ "type": "Link",
+ "src_node": "core1",
+ "dst_node": "core2",
+ "groups": [ "virtual" ]
+ },
+ {
+ "type": "Link",
+ "src_node": "core2",
+ "dst_node": "prod",
+ "groups": [ "virtual" ]
+ },
+ {
+ "type": "CentralIP",
+ "ip4_data_prefix": "192.168.42.0/24",
+ "ip6_data_prefix": "9002::/16",
+ "ip_routing_strategy": "spt",
+ "groups": [
+ "virtual"
+ ]
+ },
+ {
+ "type": "MetisForwarder",
+ "cache_size": 0,
+ "node": "cons"
+ },
+ {
+ "type": "MetisForwarder",
+ "cache_size": 2000,
+ "node": "core1"
+ },
+ {
+ "type": "MetisForwarder",
+ "cache_size": 0,
+ "node": "core2"
+ },
+ {
+ "type": "MetisForwarder",
+ "cache_size": 0,
+ "node": "prod"
+ },
+ {
+ "type": "WebServer",
+ "prefixes": [
+ "/webserver"
+ ],
+ "node": "prod"
+ },
+ {
+ "type": "CentralICN",
+ "groups": [ "virtual" ],
+ "face_protocol": "udp4"
+ }
+ ]
+}
diff --git a/netmodel/interfaces/process/__init__.py b/netmodel/interfaces/process/__init__.py
index 59bf6f9f..9f3d3c11 100644
--- a/netmodel/interfaces/process/__init__.py
+++ b/netmodel/interfaces/process/__init__.py
@@ -90,7 +90,7 @@ class BWMThread(Process):
if line:
record = self._parse_line(line.strip())
# We use 'total' to push the statistics back to VICN
- if record['iface_name'] == 'total':
+ if record.get('iface_name') == 'total':
for interfaces in self.groups_of_interfaces:
if not len(interfaces) > 1:
# If the tuple contains only one interface, grab
diff --git a/vicn/core/resource.py b/vicn/core/resource.py
index 878a8108..a80e09ed 100644
--- a/vicn/core/resource.py
+++ b/vicn/core/resource.py
@@ -467,7 +467,7 @@ class BaseResource(Object): #, ABC, metaclass=ResourceMetaclass):
self._state.manager.attribute_set(self, attribute_name, value)
async def async_set(self, attribute_name, value, current=False,
- set_reverse=True, blocking=None):
+ set_reverse=True):
"""
Example:
- setting the ip address on a node's interface
@@ -478,7 +478,12 @@ class BaseResource(Object): #, ABC, metaclass=ResourceMetaclass):
"""
value = self._set(attribute_name, value, current=current,
set_reverse=set_reverse)
- await self._state.manager.attribute_set_async(self, attribute_name, value)
+ if self.is_local_attribute(attribute_name) or current:
+ if value is None:
+ attribute = self.get_attribute(attribute_name)
+ vars(self)[attribute_name] = value
+ else:
+ await self._state.manager.attribute_async_set(self, attribute_name, value)
def set_many(self, attribute_dict, current=False):
if not attribute_dict:
diff --git a/vicn/core/resource_mgr.py b/vicn/core/resource_mgr.py
index 8db7f04d..b4aa6bb7 100644
--- a/vicn/core/resource_mgr.py
+++ b/vicn/core/resource_mgr.py
@@ -587,7 +587,7 @@ class ResourceManager(metaclass=Singleton):
await self.wait_attr_init(resource, attribute)
return resource.get(attribute)
- async def _attribute_set(self, resource, attribute_name, value):
+ async def _attribute_set(self, resource, attribute_name, value, blocking=False):
with await resource._state.write_lock:
attr_state = resource._state.attr_state[attribute_name]
@@ -632,8 +632,8 @@ class ResourceManager(metaclass=Singleton):
raise RuntimeError("Resource cannot be in state".format(
resource_state))
-# if blocking:
-# await self.wait_attr_clean(resource, attribute_name)
+ if blocking:
+ await self.wait_attr_clean(resource, attribute_name)
def attribute_set(self, resource, attribute_name, value):
# Add the current operation to the pending list
@@ -643,15 +643,13 @@ class ResourceManager(metaclass=Singleton):
value)
asyncio.ensure_future(self._attribute_set(resource, attribute_name, value))
- async def attribute_set_async(self, resource, attribute_name, value):
+ async def attribute_async_set(self, resource, attribute_name, value):
# Add the current operation to the pending list
# NOTE: collections are unordered and can be updated concurrently
#self._attribute_set_pending_value(resource, attribute_name)
resource._state.dirty[attribute_name].trigger(Operations.SET,
value)
- await self._attribute_set(resource, attribute_name, value)
-
-
+ await self._attribute_set(resource, attribute_name, value, blocking=True)
#---------------------------------------------------------------------------
# Resource dependency management
diff --git a/vicn/resource/icn/central.py b/vicn/resource/icn/central.py
index aa8ea357..fd272bf6 100644
--- a/vicn/resource/icn/central.py
+++ b/vicn/resource/icn/central.py
@@ -81,6 +81,8 @@ class ICNFaces(Resource):
def __delete__(self):
raise NotImplementedError
+ def __after__(self):
+ return ("VPPInterface",)
#--------------------------------------------------------------------------
# Internal methods
#--------------------------------------------------------------------------
@@ -102,7 +104,11 @@ class ICNFaces(Resource):
map_ = data['map_node_interface']
src = self._state.manager.by_uuid(map_[src_node_uuid])
+ if src.has_vpp_child:
+ src = src.vppinterface
dst = self._state.manager.by_uuid(map_[dst_node_uuid])
+ if dst.has_vpp_child:
+ dst = dst.vppinterface
log.debug('{} -> {} ({} -> {})'.format(src_node_uuid,
dst_node_uuid, src.device_name, dst.device_name))
diff --git a/vicn/resource/icn/cicn.py b/vicn/resource/icn/cicn.py
index 8ab36ec9..597692c8 100644
--- a/vicn/resource/icn/cicn.py
+++ b/vicn/resource/icn/cicn.py
@@ -71,7 +71,7 @@ class CICNForwarder(Forwarder):
@inherit_parent
def __get__(self):
def parse(rv):
- if rv.return_value > 0 or 'cicn: not enabled' in rv.stdout:
+ if rv.return_value > 0 or 'cicn: not enabled' in rv.stdout or "Forwarder : disabled" in rv.stdout:
raise ResourceNotFound
return BashTask(self.node, CMD_VPP_CICN_GET,
lock = self.node.vpp.vppctl_lock, parse=parse)
@@ -134,6 +134,9 @@ class CICNForwarder(Forwarder):
def _get_cache_size(self):
def parse(rv):
- return int(rv.stdout)
+ if not rv.stdout:
+ return 0
+ else:
+ return int(rv.stdout)
return BashTask(self.node, CMD_VPP_CICN_GET_CACHE_SIZE, parse=parse,
lock = self.node.vpp.vppctl_lock)
diff --git a/vicn/resource/ip/central.py b/vicn/resource/ip/central.py
index 0c397728..75b590e1 100644
--- a/vicn/resource/ip/central.py
+++ b/vicn/resource/ip/central.py
@@ -82,7 +82,8 @@ class IPRoutes(Resource):
node_uuid = interface.node._state.uuid
if not node_uuid in origins:
origins[node_uuid] = list()
- origins[node_uuid].append(interface.ip4_address.canonical_prefix())
+ if interface.ip4_address:
+ origins[node_uuid].append(interface.ip4_address.canonical_prefix())
if interface.ip6_address:
origins[node_uuid].append(interface.ip6_address.canonical_prefix())
return origins
@@ -113,7 +114,6 @@ class IPRoutes(Resource):
# Avoid duplicate routes due to multiple paths in the network
if not src_node in ip_routes:
ip_routes[src_node] = set()
- #XXX Untested for VPP
#When you set up an IP address ip/prefix_len (ip addr add), you already create a route
#towards ip/prefix_len
for interface in src_node.interfaces:
diff --git a/vicn/resource/lxd/lxc_container.py b/vicn/resource/lxd/lxc_container.py
index a9f8483d..3222cc8a 100644
--- a/vicn/resource/lxd/lxc_container.py
+++ b/vicn/resource/lxd/lxc_container.py
@@ -19,6 +19,7 @@
import logging
import shlex
import time
+import requests
# Suppress logging from pylxd dependency on ws4py
# (this needs to be included before pylxd)
diff --git a/vicn/resource/vpp/interface.py b/vicn/resource/vpp/interface.py
index 9dbd7fc3..f845e2df 100644
--- a/vicn/resource/vpp/interface.py
+++ b/vicn/resource/vpp/interface.py
@@ -34,11 +34,18 @@ from vicn.resource.vpp.vpp_commands import CMD_VPP_CREATE_IFACE, CMD_VPP_CREATE_
from vicn.resource.vpp.vpp_commands import CMD_VPP_SET_IP, CMD_VPP_SET_UP
from vicn.resource.vpp.memif_device import MemifDevice
+VPP_vers = (17, 7)
+
GREP_MEMIF_INFO = 'vppctl_wrapper show memif | grep interface --no-group-separator -A 1'
def parse_memif(rv, vppinterface):
kw_interface = pp.CaselessKeyword('interface')
kw_key = pp.CaselessKeyword('key')
+ kw_remote_name = pp.CaselessKeyword('remote-name')
+ kw_remote_if = pp.CaselessKeyword('remote-interface')
+ kw_id = pp.CaselessKeyword('id')
+ kw_mode = pp.CaselessKeyword('mode')
+ kw_ethernet = pp.CaselessKeyword('ethernet')
kw_file = pp.CaselessKeyword('file')
kw_listener = pp.CaselessKeyword('listener')
kw_connfd = pp.CaselessKeyword('conn-fd')
@@ -51,20 +58,41 @@ def parse_memif(rv, vppinterface):
r_path = ' *(/[a-zA-Z0-9_\-]*)*\.[a-zA-Z0-9_\-]*'
r_id = ' *-+[0-9]*'
- single = kw_interface.suppress() + pp.Word(pp.alphanums).setResultsName('interface') + \
- kw_key.suppress() + pp.Word(pp.alphanums).setResultsName('key') + \
- kw_file.suppress() + pp.Regex(r_path).setResultsName('path') # + \
- # kw_listener.suppress() + pp.Word(pp.alphanums).setResultsName('listener') + \
- # kw_connfd.suppress() + pp.Regex(r_id).setResultsName('conn-fd') + \
- # kw_intfd.suppress() + pp.Regex(r_id).setResultsName('int-fd') + \
- # kw_ringsize.suppress() + pp.Word(pp.nums).setResultsName('ring-size') + \
- # kw_numc2srings.suppress() + pp.Word(pp.nums).setResultsName('num-c2s-rings') + \
- # kw_nums2crings.suppress() + pp.Word(pp.nums).setResultsName('num-s2c-rings') + \
- # kw_buffersize.suppress() + pp.Word(pp.nums).setResultsName('buffer-size')
+ r_remote_name = '"[A-Z]+ [0-9\.]+-[a-z]+"'
+ r_remote_if = '"[a-zA-Z0-9_\-]+"'
+
+ if VPP_vers >= (17, 7):
+ single = kw_interface.suppress() + pp.Word(pp.alphanums).setResultsName('interface') + \
+ pp.Optional(kw_remote_name.suppress() + pp.Regex(r_remote_name).setResultsName('remote_name') + \
+ kw_remote_if.suppress() + pp.Regex(r_remote_if).setResultsName('remote_if')) + \
+ kw_id.suppress() + pp.Word(pp.alphanums).setResultsName('key') + \
+ kw_mode.suppress() + kw_ethernet.suppress() + \
+ kw_file.suppress() + pp.Regex(r_path).setResultsName('path') # + \
+ # kw_listener.suppress() + pp.Word(pp.alphanums).setResultsName('listener') + \
+ # kw_connfd.suppress() + pp.Regex(r_id).setResultsName('conn-fd') + \
+ # kw_intfd.suppress() + pp.Regex(r_id).setResultsName('int-fd') + \
+ # kw_ringsize.suppress() + pp.Word(pp.nums).setResultsName('ring-size') + \
+ # kw_numc2srings.suppress() + pp.Word(pp.nums).setResultsName('num-c2s-rings') + \
+ # kw_nums2crings.suppress() + pp.Word(pp.nums).setResultsName('num-s2c-rings') + \
+ # kw_buffersize.suppress() + pp.Word(pp.nums).setResultsName('buffer-size')
+ else:
+ single = kw_interface.suppress() + pp.Word(pp.alphanums).setResultsName('interface') + \
+ kw_key.suppress() + pp.Word(pp.alphanums).setResultsName('key') + \
+ kw_file.suppress() + pp.Regex(r_path).setResultsName('path') # + \
+ # kw_listener.suppress() + pp.Word(pp.alphanums).setResultsName('listener') + \
+ # kw_connfd.suppress() + pp.Regex(r_id).setResultsName('conn-fd') + \
+ # kw_intfd.suppress() + pp.Regex(r_id).setResultsName('int-fd') + \
+ # kw_ringsize.suppress() + pp.Word(pp.nums).setResultsName('ring-size') + \
+ # kw_numc2srings.suppress() + pp.Word(pp.nums).setResultsName('num-c2s-rings') + \
+ # kw_nums2crings.suppress() + pp.Word(pp.nums).setResultsName('num-s2c-rings') + \
+ # kw_buffersize.suppress() + pp.Word(pp.nums).setResultsName('buffer-size')
multiple = pp.OneOrMore(pp.Group(single))
- results = multiple.parseString(rv.stdout)
+ try:
+ results = multiple.parseString(rv.stdout)
+ except Exception as e:
+ import pdb; pdb.set_trace()
for interface in results:
if interface['path'] == vppinterface.parent.path_unix_socket + vppinterface.parent.socket_name:
@@ -108,7 +136,7 @@ class VPPInterface(Resource):
"""
We need CentralIP to get the parent interface IP address
"""
- return ['CentralIP']
+ return ['CentralIP', 'IpAssignment']
@inherit_parent
@inline_task
@@ -126,9 +154,23 @@ class VPPInterface(Resource):
self.parent.has_vpp_child = True
self.up = True
+ self.ip4_address = self.parent.ip4_address
+ self.ip6_address = self.parent.ip6_address
+
if isinstance(self.parent, MemifDevice):
+ self.device_name = self.parent.device_name
+
#TODO: add output parsing to get the interface name
- create_task = BashTask(self.vpp.node, CMD_VPP_CREATE_MEMIFACE, {
+ if VPP_vers >= (17, 7):
+ create_task = BashTask(self.vpp.node, CMD_VPP_CREATE_MEMIFACE, {
+ 'key_label': 'id',
+ 'key': self.parent.key,
+ 'vpp_interface': self,
+ 'master_slave': 'master' if self.parent.master else 'slave'},
+ lock = self.vpp.vppctl_lock)
+ else:
+ create_task = BashTask(self.vpp.node, CMD_VPP_CREATE_MEMIFACE, {
+ 'key_label': 'key',
'key': hex(self.parent.key),
'vpp_interface': self,
'master_slave': 'master' if self.parent.master else 'slave'},
@@ -143,8 +185,8 @@ class VPPInterface(Resource):
# Remove ip address in the parent device, it must only be set in
# the vpp interface otherwise vpp and the linux kernel will reply
# to non-icn request (e.g., ARP replies, port ureachable etc)
- self.ip4_address = self.parent.ip4_address
- self.ip6_address = self.parent.ip6_address
+ self.parent.ip4_address = None
+ self.parent.ip6_address = None
self.device_name = 'host-' + self.parent.device_name
create_task = BashTask(self.vpp.node, CMD_VPP_CREATE_IFACE,
@@ -155,8 +197,6 @@ class VPPInterface(Resource):
self.parent.remote.set('offload', False)
elif self.parent.get_type() == 'dpdkdevice':
- self.ip4_address = self.parent.ip4_address
- self.ip6_address = self.parent.ip6_address
self.device_name = self.parent.device_name
else :
# Currently assume naively that everything else will be a physical
diff --git a/vicn/resource/vpp/memif_link.py b/vicn/resource/vpp/memif_link.py
index 62de03c6..25cfeea3 100644
--- a/vicn/resource/vpp/memif_link.py
+++ b/vicn/resource/vpp/memif_link.py
@@ -90,7 +90,7 @@ class MemifLink(Channel):
foldername = SHARED_FOLDER_PATH.format(self.src_node.name + '-' + self.dst_node.name),
permission = 777)
- self.key = random.randint(0, 2**64)
+ self.key = random.randint(0, 2**31)
self._src = MemifDevice(node = self.src_node,
channel = self,
diff --git a/vicn/resource/vpp/scripts.py b/vicn/resource/vpp/scripts.py
index 06da7404..b467df6c 100644
--- a/vicn/resource/vpp/scripts.py
+++ b/vicn/resource/vpp/scripts.py
@@ -282,7 +282,7 @@ api-segment {
'''
APPARMOR_VPP_PROFILE = '''
-lxc.aa_profile = lxc-dpdk
+lxc.apparmor.profile = lxc-dpdk
lxc.mount.entry = hugetlbfs dev/hugepages hugetlbfs rw,relatime,create=dir 0 0
lxc.mount.auto = sys:rw'''
diff --git a/vicn/resource/vpp/vpp.py b/vicn/resource/vpp/vpp.py
index 9d4f7068..a185c039 100644
--- a/vicn/resource/vpp/vpp.py
+++ b/vicn/resource/vpp/vpp.py
@@ -147,7 +147,10 @@ class VPP(LinuxApplication):
if numa in socket_mem:
socket_mem_str = socket_mem_str + str(socket_mem[numa])
else:
- socket_mem_str = socket_mem_str + '0'
+ if None in socket_mem: #No numa nodes on machine but DpdkDevice has socket mem
+ socket_mem_str = socket_mem_str+str(socket_mem[None])
+ else:
+ socket_mem_str = socket_mem_str + '0'
if numa < numa_mgr.get_number_of_numa()-1:
socket_mem_str = socket_mem_str + ','
diff --git a/vicn/resource/vpp/vpp_commands.py b/vicn/resource/vpp/vpp_commands.py
index acc89640..e0b71517 100644
--- a/vicn/resource/vpp/vpp_commands.py
+++ b/vicn/resource/vpp/vpp_commands.py
@@ -6,6 +6,7 @@ CMD_VPP_DISABLE = 'systemctl disable vpp.service'
# 'sleep 1' ensures that VPP has enough time to start
CMD_VPP_START = '''
flock /tmp/vppctl.lock -c "systemctl start vpp"
+sleep 2
'''
CMD_VPP_STOP = '''
flock /tmp/vppctl.lock -c "systemctl stop vpp"
@@ -25,7 +26,7 @@ vppctl_wrapper set interface state {vpp_interface.device_name} up
# generated by VPP, preventing any reboot of VPP and recreation of commands
CMD_VPP_CREATE_MEMIFACE = '''
# Create vpp interface from shared_memory
-vppctl_wrapper create memif key {key} socket {vpp_interface.parent.path_unix_socket}{vpp_interface.parent.socket_name} hw-addr {vpp_interface.parent.mac_address} {master_slave}
+vppctl_wrapper create memif {key_label} {key} socket {vpp_interface.parent.path_unix_socket}{vpp_interface.parent.socket_name} hw-addr {vpp_interface.parent.mac_address} {master_slave}
'''
CMD_VPP_SET_IP = 'vppctl_wrapper set int ip address {device_name} {ip_address}/{prefix_len}'
CMD_VPP_SET_UP = 'vppctl_wrapper set int state {netdevice.device_name} {state}'
diff --git a/www/img/smartphone.png b/www/img/smartphone.png
new file mode 100644
index 00000000..a550603c
--- /dev/null
+++ b/www/img/smartphone.png
@@ -0,0 +1,17 @@
+<!DOCTYPE html><html lang="en"><head><meta charset="utf-8"><meta http-equiv="X-UA-Compatible" content="IE=edge"><title>Log in - Bitbucket Engineering - GPK1</title><script>
+window.WRM=window.WRM||{};window.WRM._unparsedData=window.WRM._unparsedData||{};window.WRM._unparsedErrors=window.WRM._unparsedErrors||{};
+WRM._unparsedData["com.atlassian.plugins.atlassian-plugins-webresource-plugin:context-path.context-path"]="\u0022\u005C/bitbucket\u0022";
+WRM._unparsedData["com.atlassian.bitbucket.server.feature-wrm-data:nps.survey.inline.dialog.data"]="true";
+WRM._unparsedData["com.atlassian.bitbucket.server.feature-wrm-data:nps.experiment.enabled.by.sen.data"]="false";
+WRM._unparsedData["com.atlassian.analytics.analytics-client:policy-update-init.policy-update-data-provider"]="false";
+WRM._unparsedData["com.atlassian.analytics.analytics-client:programmatic-analytics-init.programmatic-analytics-data-provider"]="false";
+WRM._unparsedData["com.atlassian.bitbucket.server.feature-wrm-data:user.time.zone.onboarding.data"]="true";
+WRM._unparsedData["com.onresolve.stash.groovy.groovyrunner:web-item-response-renderer.web-item-actions-data-provider"]="[]";
+if(window.WRM._dataArrived)window.WRM._dataArrived();</script>
+<link type="text/css" rel="stylesheet" href="/bitbucket/s/82df8258d43f2df4e9585366ca557b2f-CDN/-939794491/2d88633/1/f6c15e06311faedbd487c69e6f778cd6/_/download/contextbatch/css/_super/batch.css" data-wrm-key="_super" data-wrm-batch-type="context" media="all">
+<link type="text/css" rel="stylesheet" href="/bitbucket/s/96d1ecf23add4e429d5b6ac78be1cee6-CDN/-939794491/2d88633/1/ea28cfaf2acbe7b82e7be0a0260044b0/_/download/contextbatch/css/bitbucket.page.login,-_super/batch.css" data-wrm-key="bitbucket.page.login,-_super" data-wrm-batch-type="context" media="all">
+<link type="text/css" rel="stylesheet" href="/bitbucket/s/5a3a87ce25d238c0d4002dc9c05fbf0c-CDN/-939794491/2d88633/1/e3a624d4fc67a5cb809b2d1170261aba/_/download/contextbatch/css/bitbucket.layout.focused,bitbucket.layout.base,atl.general,-_super/batch.css?analytics-enabled=true&amp;analytics-uploadable=true&amp;nps-acknowledged=true&amp;supportedApplication=true" data-wrm-key="bitbucket.layout.focused,bitbucket.layout.base,atl.general,-_super" data-wrm-batch-type="context" media="all">
+<script type="text/javascript" src="/bitbucket/s/2faa0515c8c366460fd78a389fc54d62-CDN/-939794491/2d88633/1/f6c15e06311faedbd487c69e6f778cd6/_/download/contextbatch/js/_super/batch.js?locale=en-US" data-wrm-key="_super" data-wrm-batch-type="context" data-initially-rendered></script>
+<script type="text/javascript" src="/bitbucket/s/4a4cfef7b765f19375f9b621da68887c-CDN/-939794491/2d88633/1/ea28cfaf2acbe7b82e7be0a0260044b0/_/download/contextbatch/js/bitbucket.page.login,-_super/batch.js?locale=en-US" data-wrm-key="bitbucket.page.login,-_super" data-wrm-batch-type="context" data-initially-rendered></script>
+<script type="text/javascript" src="/bitbucket/s/d56f03b50edb7c9704be7e094abecc22-CDN/-939794491/2d88633/1/e3a624d4fc67a5cb809b2d1170261aba/_/download/contextbatch/js/bitbucket.layout.focused,bitbucket.layout.base,atl.general,-_super/batch.js?analytics-enabled=true&amp;analytics-uploadable=true&amp;locale=en-US&amp;nps-acknowledged=true&amp;supportedApplication=true" data-wrm-key="bitbucket.layout.focused,bitbucket.layout.base,atl.general,-_super" data-wrm-batch-type="context" data-initially-rendered></script>
+<meta name="application-name" content="Bitbucket"><link rel="shortcut icon" type="image/x-icon" href="/bitbucket/s/-939794491/2d88633/1/1.0/_/download/resources/com.atlassian.bitbucket.server.bitbucket-web:favicon/favicon.ico" /><link rel="search" href="https://bitbucket-eng-gpk1.cisco.com/bitbucket/plugins/servlet/opensearch-descriptor" type="application/opensearchdescription+xml" title="Bitbucket code search" /></head><body class="aui-page-focused aui-page-focused-small aui-page-size-small bitbucket-theme user-login"><ul id="assistive-skip-links" class="assistive"><li><a href="#content">Skip to content</a></li></ul><div id="page"><!-- start #header --><header id="header" role="banner"><section class="notifications"></section><nav class="aui-header aui-dropdown2-trigger-group" role="navigation"><div class="aui-header-inner"><div class="aui-header-before"><a class=" aui-dropdown2-trigger app-switcher-trigger" aria-controls="app-switcher" aria-haspopup="true" role="button" tabindex="0" data-aui-trigger href="#app-switcher"><span class="aui-icon aui-icon-small aui-iconfont-appswitcher">Linked Applications</span></a><div id="app-switcher" class="aui-dropdown2 aui-style-default" role="menu" aria-hidden="true" data-is-switcher="true" data-environment="{&quot;isUserAdmin&quot;:false,&quot;isAppSuggestionAvailable&quot;:false,&quot;isSiteAdminUser&quot;:false}"><div role="application"><div class="app-switcher-loading">Loading&hellip;</div></div></div></div><div class="aui-header-primary"><h1 id="logo" class="aui-header-logo aui-header-logo-bitbucket"><a href="https://bitbucket-eng-gpk1.cisco.com/bitbucket" class="stash"><span class="aui-header-logo-device">Bitbucket</span></a></h1><meta name="stp-license-product-name" content="Bitbucket"/> <meta name="stp-license-days-to-expiry" content="195"/> <meta name="stp-license-is-admin" content="false"/> <meta name="stp-license-should-keep-banner-hidden" content="true"/><ul class="aui-nav"></ul></div><div class="aui-header-secondary"><ul class="aui-nav"><li class=" help-link"title="Help"><a class=" aui-dropdown2-trigger aui-dropdown2-trigger-arrowless" aria-controls="com.atlassian.bitbucket.server.bitbucket-server-web-fragments-help-menu" aria-haspopup="true" role="button" tabindex="0" data-aui-trigger><span class="aui-icon aui-icon-small aui-iconfont-help">Help</span><span class="icon aui-icon-dropdown"></span></a><div id="com.atlassian.bitbucket.server.bitbucket-server-web-fragments-help-menu" class="aui-dropdown2 aui-style-default" role="menu" aria-hidden="true"><div role="application"><div class="aui-dropdown2-section help-items-section"><ul class="aui-list-truncate" role="presentation"><li role="presentation"><a href="http://docs.atlassian.com/bitbucketserver/docs-0414/Bitbucket+Server+Documentation+Home?utm_campaign=in-app-help&amp;amp;utm_medium=in-app-help&amp;amp;utm_source=stash" title="Go to the online documentation for Bitbucket" data-web-item-key="com.atlassian.bitbucket.server.bitbucket-server-web-fragments:general-help">Online help</a></li><li role="presentation"><a href="https://www.atlassian.com/git?utm_campaign=learn-git&amp;utm_medium=in-app-help&amp;utm_source=stash" title="Learn about Git commands &amp; workflows" data-web-item-key="com.atlassian.bitbucket.server.bitbucket-server-web-fragments:learn-git">Learn Git</a></li><li role="presentation"><a href="/bitbucket/getting-started" class="getting-started-page-link" title="Overview of Bitbucket features" data-web-item-key="com.atlassian.bitbucket.server.bitbucket-server-web-fragments:getting-started-page-help-link">Welcome to Bitbucket</a></li><li role="presentation"><a href="/bitbucket/#" class="keyboard-shortcut-link" title="Discover keyboard shortcuts in Bitbucket" data-web-item-key="com.atlassian.bitbucket.server.bitbucket-server-web-fragments:keyboard-shortcuts-help-link">Keyboard shortcuts</a></li></ul></div></div></div></li><li class=" alerts-menu"title="View system alerts"><a href="#alerts" id="alerts-trigger" class="alerts-menu" title="View system alerts" data-web-item-key="com.atlassian.bitbucket.server.bitbucket-server-web-fragments:global-alerts-menu-item">Alerts</a></li></ul></div></div> <!-- End .aui-header-inner --></nav> <!-- End .aui-header --></header><!-- End #header --><!-- Start #content --><section id="content" role="main" tabindex="-1" data-timezone="0" ><div class="aui-page-panel content-body"><div class="aui-page-panel-inner"><section class="aui-page-panel-content"><h2>Log in</h2><form class="aui top-label prevent-double-submit " action="/bitbucket/j_atl_security_check" method="post" accept-charset="UTF-8"><div class="field-group"><label for="j_username" >Username</label><input class="text long-field" type="text" id="j_username" name="j_username" autofocus accesskey="u"/></div><div class="field-group"><label for="j_password" >Password</label><input class="text long-field" type="password" id="j_password" name="j_password" accesskey="p"/></div><div class="aui-group"><fieldset class="group checkbox"><div class="checkbox"><input class="checkbox" type="checkbox" id="_atl_remember_me" name="_atl_remember_me" checked="checked" accesskey="r"/><label for="_atl_remember_me" >Keep me logged in</label></div></fieldset></div><div class="aui-group"><input name="next" type="hidden" value="/projects/ICN/repos/vicn/raw/www/img/smartphone.png?at=refs%2Fheads%2Fhicn"/><input class="aui-button aui-button-primary" type="submit" id="submit" name="submit" value="Log in" accesskey="s"/><a id="forgot" class="aui-button aui-button-link" name="forgot" href="/bitbucket/passwordreset" autocomplete="off" tabindex="0">Unable to access your account?</a></div></form></section><!-- .aui-page-panel-content --></div><!-- .aui-page-panel-inner --></div><!-- .aui-page-panel --></section><!-- End #content --><!-- Start #footer --><footer id="footer" role="contentinfo"><section class="notifications"></section><section class="footer-body"><ul><li data-key="footer.license.message">Git repository management for enterprise teams powered by <a href="http://www.atlassian.com/software/bitbucket/">Atlassian Bitbucket</a></li></ul><ul><li>Atlassian Bitbucket <span title="2d88633916d4728474f8176943c3902a66488f86" id="product-version" data-commitid="2d88633916d4728474f8176943c3902a66488f86" data-system-build-number="2d88633"> v4.14.5</span></li><li data-key="footer.links.documentation"><a href="http://docs.atlassian.com/bitbucketserver/docs-0414/Bitbucket+Server+Documentation+Home?utm_campaign=in-app-help&amp;utm_medium=in-app-help&amp;utm_source=stash" target="_blank">Documentation</a></li><li data-key="footer.links.contact.support"><a href="https://support.atlassian.com/secure/SENVerification.jspa?issuetype=1&pid=10740" target="_blank">Contact Support</a></li><li data-key="footer.links.jac"><a href="https://jira.atlassian.com/browse/BSERV" target="_blank">Request a feature</a></li><li data-key="footer.links.about"><a href="/bitbucket/about">About</a></li><li data-key="footer.links.contact.atlassian"><a href="http://www.atlassian.com/company/contact/" target="_blank">Contact Atlassian</a></li></ul><div id="footer-logo"><a href="http://www.atlassian.com/" target="_blank">Atlassian</a></div></section></footer><!-- End #footer --></div><script>require('bitbucket/internal/layout/base').onReady(null, "Bitbucket Engineering - GPK1" ); require('bitbucket/internal/widget/keyboard-shortcuts').onReady();</script><script type="text/javascript">require('bitbucket/internal/page/login').onReady();</script></body></html> \ No newline at end of file