See the License for the specific language governing permissions and
limitations under the License.
-Neither the name of the SONATA-NFV [, ANY ADDITIONAL AFFILIATION]
+Neither the name of the SONATA-NFV, Paderborn University
nor the names of its contributors may be used to endorse or promote
products derived from this software without specific prior written
permission.
from random import randint
import ipaddress
import copy
+import time
logging.basicConfig()
LOG = logging.getLogger("sonata-dummy-gatekeeper")
# path to the VNFD for the SAP VNF that is deployed as internal SAP point
SAP_VNFD=None
+# Time in seconds to wait for vnf stop scripts to execute fully
+VNF_STOP_WAIT_TIME = 5
+
class Gatekeeper(object):
def __init__(self):
self.local_docker_files = dict()
self.remote_docker_image_urls = dict()
self.instances = dict()
- #self.vnf_name2docker_name = dict()
# dict to find the vnf_name for any vnf id
self.vnf_id2vnf_name = dict()
self._start_sap(self.saps[sap], instance_uuid)
# 5. Deploy E-Line and E_LAN links
- if "virtual_links" in self.nsd:
+ # Attention: Only done if ""forwarding_graphs" section in NSD exists,
+ # even if "forwarding_graphs" are not used directly.
+ if "virtual_links" in self.nsd and "forwarding_graphs" in self.nsd:
vlinks = self.nsd["virtual_links"]
# constituent virtual links are not checked
#fwd_links = self.nsd["forwarding_graphs"][0]["constituent_virtual_links"]
# instance_uuid = str(self.uuid.uuid4())
vnf_instances = self.instances[instance_uuid]["vnf_instances"]
+ # trigger stop skripts in vnf instances and wait a few seconds for completion
+ self._trigger_emulator_stop_scripts_in_vnfis(vnf_instances)
+ time.sleep(VNF_STOP_WAIT_TIME)
+
for v in vnf_instances:
self._stop_vnfi(v)
for sap_name in self.saps_ext:
ext_sap = self.saps[sap_name]
target_dc = ext_sap.get("dc")
- target_dc.removeExternalSAP(sap_name, ext_sap['net'])
+ target_dc.removeExternalSAP(sap_name)
LOG.info("Stopping the SAP instance: %r in DC %r" % (sap_name, target_dc))
if not GK_STANDALONE_MODE:
# last step: remove the instance from the list of all instances
del self.instances[instance_uuid]
- def _start_vnfd(self, vnfd, vnf_id):
+ def _start_vnfd(self, vnfd, vnf_id, **kwargs):
"""
Start a single VNFD of this service
:param vnfd: vnfd descriptor dict
# 3. get the resource limits
res_req = u.get("resource_requirements")
cpu_list = res_req.get("cpu").get("cores")
- if not cpu_list or len(cpu_list)==0:
+ if cpu_list is None:
+ cpu_list = res_req.get("cpu").get("vcpus")
+ if cpu_list is None:
cpu_list="1"
cpu_bw = res_req.get("cpu").get("cpu_bw")
if not cpu_bw:
cpu_period=cpu_period,
cpuset=cpu_list,
mem_limit=mem_lim,
- volumes=volumes)
+ volumes=volumes,
+ type=kwargs.get('type','docker'))
# rename the docker0 interfaces (eth0) to the management port name defined in the VNFD
if USE_DOCKER_MGMT:
:return:
"""
dn = vnf_id
- #if vnf_id in self.vnf_name2docker_name:
- # dn = self.vnf_name2docker_name[name]
for vnfi in self.instances[instance_uuid]["vnf_instances"]:
if vnfi.name == dn:
return vnfi
t.daemon = True
t.start()
+ def _trigger_emulator_stop_scripts_in_vnfis(self, vnfi_list):
+ for vnfi in vnfi_list:
+ config = vnfi.dcinfo.get("Config", dict())
+ env = config.get("Env", list())
+ for env_var in env:
+ var, cmd = map(str.strip, map(str, env_var.split('=', 1)))
+ if var=="SON_EMU_CMD_STOP":
+ LOG.info("Executing stop script in %r: %r" % (vnfi.name, cmd))
+ # execute command in new thread to ensure that GK is not blocked by VNF
+ t = threading.Thread(target=vnfi.cmdPrint, args=(cmd,))
+ t.daemon = True
+ t.start()
+
+
+
def _unpack_service_package(self):
"""
unzip *.son file and store contents in CATALOG_FOLDER/services/<service_uuid>/
if sap["type"] == "internal":
vnfi = None
if not GK_STANDALONE_MODE:
- vnfi = self._start_vnfd(sap, sap['name'])
+ vnfi = self._start_vnfd(sap, sap['name'], type='sap_int')
self.instances[instance_uuid]["vnf_instances"].append(vnfi)
elif sap["type"] == "external":
src_id = src_sap_id
# set intf name to None so the chaining function will choose the first one
src_if_name = None
- #src_name = self.vnf_id2vnf_name[src_id]
- #dst_name = self.vnf_id2vnf_name[dst_id]
dst_vnfi = self._get_vnf_instance(instance_uuid, dst_id)
if dst_vnfi is not None:
# choose first ip address in sap subnet
dst_id = dst_sap_id
# set intf name to None so the chaining function will choose the first one
dst_if_name = None
- #src_name = self.vnf_id2vnf_name[src_id]
- #dst_name = self.vnf_id2vnf_name[dst_id]
src_vnfi = self._get_vnf_instance(instance_uuid, src_id)
if src_vnfi is not None:
sap_net = self.saps[dst_sap_id]['net']
src_id = src_sap_id
if dst_sap_id in self.saps_int:
dst_id = dst_sap_id
- #src_name = self.vnf_id2vnf_name[src_id]
- #dst_name = self.vnf_id2vnf_name[dst_id]
# re-configure the VNFs IP assignment and ensure that a new subnet is used for each E-Link
src_vnfi = self._get_vnf_instance(instance_uuid, src_id)
dst_vnfi = self._get_vnf_instance(instance_uuid, dst_id)
src_docker_name = vnf_sap_id
vnf_id = vnf_sap_id
- #vnf_name = self.vnf_id2vnf_name[vnf_id]
LOG.debug(
- "Setting up E-LAN interface. %s(%s:%s) -> %s" % (
+ "Setting up E-LAN interface. (%s:%s) -> %s" % (
vnf_id, intf_name, ip_address))
- if vnf_id in self.vnfds:
- # re-configure the VNFs IP assignment and ensure that a new subnet is used for each E-LAN
- # E-LAN relies on the learning switch capability of Ryu which has to be turned on in the topology
- # (DCNetwork(controller=RemoteController, enable_learning=True)), so no explicit chaining is necessary.
- vnfi = self._get_vnf_instance(instance_uuid, vnf_id)
- if vnfi is not None:
- self._vnf_reconfigure_network(vnfi, intf_name, ip_address)
- # add this vnf and interface to the E-LAN for tagging
- elan_vnf_list.append({'name': src_docker_name, 'interface': intf_name})
+ # re-configure the VNFs IP assignment and ensure that a new subnet is used for each E-LAN
+ # E-LAN relies on the learning switch capability of Ryu which has to be turned on in the topology
+ # (DCNetwork(controller=RemoteController, enable_learning=True)), so no explicit chaining is necessary.
+ vnfi = self._get_vnf_instance(instance_uuid, vnf_id)
+ if vnfi is not None:
+ self._vnf_reconfigure_network(vnfi, intf_name, ip_address)
+ # add this vnf and interface to the E-LAN for tagging
+ elan_vnf_list.append({'name': src_docker_name, 'interface': intf_name})
# install the VLAN tags for this E-LAN
GK.net.setLAN(elan_vnf_list)
# check if there is a SAP in the link
if src_sap_id in saps:
- #dst_vnf_name = vnf_id2vnf_name[dst_id]
# get dc where connected vnf is mapped to
dc = vnfds[dst_id]['dc']
saps[src_sap_id]['dc'] = dc
if dst_sap_id in saps:
- #src_vnf_name = vnf_id2vnf_name[src_id]
# get dc where connected vnf is mapped to
dc = vnfds[src_id]['dc']
saps[dst_sap_id]['dc'] = dc