bug 425 fix SR-IOV PCI-PASSTHROUGH interfaces
Change-Id: I29528c574c05cec06ae8a4537f8398f0ca713011
Signed-off-by: tierno <alfonso.tiernosepulveda@telefonica.com>
diff --git a/openmanod b/openmanod
index 02428d7..030d4ec 100755
--- a/openmanod
+++ b/openmanod
@@ -48,7 +48,7 @@
__author__ = "Alfonso Tierno, Gerardo Garcia, Pablo Montes"
__date__ = "$26-aug-2014 11:09:29$"
-__version__ = "0.5.41-r551"
+__version__ = "0.5.42-r552"
version_date = "Nov 2017"
database_version = 27 # expected database schema version
diff --git a/osm_ro/nfvo.py b/osm_ro/nfvo.py
index e5d13eb..bd9d368 100644
--- a/osm_ro/nfvo.py
+++ b/osm_ro/nfvo.py
@@ -38,6 +38,7 @@
import vimconn
import logging
import collections
+import math
from uuid import uuid4
from db_base import db_base_Exception
@@ -852,9 +853,10 @@
vnf_uuid = str(uuid4())
uuid_list.append(vnf_uuid)
vnfd_uuid_list.append(vnf_uuid)
+ vnfd_id = get_str(vnfd, "id", 255)
db_vnf = {
"uuid": vnf_uuid,
- "osm_id": get_str(vnfd, "id", 255),
+ "osm_id": vnfd_id,
"name": get_str(vnfd, "name", 255),
"description": get_str(vnfd, "description", 255),
"tenant_id": tenant_id,
@@ -888,9 +890,10 @@
for vdu in vnfd.get("vdu").itervalues():
vm_uuid = str(uuid4())
uuid_list.append(vm_uuid)
+ vdu_id = get_str(vdu, "id", 255)
db_vm = {
"uuid": vm_uuid,
- "osm_id": get_str(vdu, "id", 255),
+ "osm_id": vdu_id,
"name": get_str(vdu, "name", 255),
"description": get_str(vdu, "description", 255),
"vnf_id": vnf_uuid,
@@ -937,6 +940,130 @@
device["image checksum"] = str(volume["image-checksum"])
devices.append(device)
+ # cloud-init
+ boot_data = {}
+ if vdu.get("cloud-init"):
+ boot_data["user-data"] = str(vdu["cloud-init"])
+ elif vdu.get("cloud-init-file"):
+ # TODO Where this file content is present???
+ # boot_data["user-data"] = vnfd_yang.files[vdu["cloud-init-file"]]
+ boot_data["user-data"] = str(vdu["cloud-init-file"])
+
+ if vdu.get("supplemental-boot-data"):
+ if vdu["supplemental-boot-data"].get('boot-data-drive'):
+ boot_data['boot-data-drive'] = True
+ if vdu["supplemental-boot-data"].get('config-file'):
+ om_cfgfile_list = list()
+ for custom_config_file in vdu["supplemental-boot-data"]['config-file'].itervalues():
+ # TODO Where this file content is present???
+ cfg_source = str(custom_config_file["source"])
+ om_cfgfile_list.append({"dest": custom_config_file["dest"],
+ "content": cfg_source})
+ boot_data['config-files'] = om_cfgfile_list
+ if boot_data:
+ db_vm["boot_data"] = yaml.safe_dump(boot_data, default_flow_style=True, width=256)
+
+ db_vms.append(db_vm)
+ db_vms_index += 1
+
+ # table interfaces (internal/external interfaces)
+ flavor_epa_interfaces = []
+ cp_name2iface_uuid = {}
+ cp_name2vm_uuid = {}
+ cp_name2db_interface = {}
+ vdu_id2cp_name = {} # stored only when one external connection point is presented at this VDU
+ # for iface in chain(vdu.get("internal-interface").itervalues(), vdu.get("external-interface").itervalues()):
+ for iface in vdu.get("interface").itervalues():
+ flavor_epa_interface = {}
+ iface_uuid = str(uuid4())
+ uuid_list.append(iface_uuid)
+ db_interface = {
+ "uuid": iface_uuid,
+ "internal_name": get_str(iface, "name", 255),
+ "vm_id": vm_uuid,
+ }
+ flavor_epa_interface["name"] = db_interface["internal_name"]
+ if iface.get("virtual-interface").get("vpci"):
+ db_interface["vpci"] = get_str(iface.get("virtual-interface"), "vpci", 12)
+ flavor_epa_interface["vpci"] = db_interface["vpci"]
+
+ if iface.get("virtual-interface").get("bandwidth"):
+ bps = int(iface.get("virtual-interface").get("bandwidth"))
+ db_interface["bw"] = int(math.ceil(bps/1000000.0))
+ flavor_epa_interface["bandwidth"] = "{} Mbps".format(db_interface["bw"])
+
+ if iface.get("virtual-interface").get("type") == "OM-MGMT":
+ db_interface["type"] = "mgmt"
+ elif iface.get("virtual-interface").get("type") in ("VIRTIO", "E1000"):
+ db_interface["type"] = "bridge"
+ db_interface["model"] = get_str(iface.get("virtual-interface"), "type", 12)
+ elif iface.get("virtual-interface").get("type") in ("SR-IOV", "PCI-PASSTHROUGH"):
+ db_interface["type"] = "data"
+ db_interface["model"] = get_str(iface.get("virtual-interface"), "type", 12)
+ flavor_epa_interface["dedicated"] = "no" if iface["virtual-interface"]["type"] == "SR-IOV" \
+ else "yes"
+ flavor_epa_interfaces.append(flavor_epa_interface)
+ else:
+ raise NfvoException("Error. Invalid VNF descriptor at 'vnfd[{}]':'vdu[{}]':'interface':'virtual"
+ "-interface':'type':'{}'. Interface type is not supported".format(
+ vnfd_id, vdu_id, iface.get("virtual-interface").get("type")),
+ HTTP_Bad_Request)
+
+ if iface.get("external-connection-point-ref"):
+ try:
+ cp = vnfd.get("connection-point")[iface.get("external-connection-point-ref")]
+ db_interface["external_name"] = get_str(cp, "name", 255)
+ cp_name2iface_uuid[db_interface["external_name"]] = iface_uuid
+ cp_name2vm_uuid[db_interface["external_name"]] = vm_uuid
+ cp_name2db_interface[db_interface["external_name"]] = db_interface
+ for cp_descriptor in vnfd_descriptor["connection-point"]:
+ if cp_descriptor["name"] == db_interface["external_name"]:
+ break
+ else:
+ raise KeyError()
+
+ if vdu_id in vdu_id2cp_name:
+ vdu_id2cp_name[vdu_id] = None # more than two connecdtion point for this VDU
+ else:
+ vdu_id2cp_name[vdu_id] = db_interface["external_name"]
+
+ # port security
+ if str(cp_descriptor.get("port-security-enabled")).lower() == "false":
+ db_interface["port_security"] = 0
+ elif str(cp_descriptor.get("port-security-enabled")).lower() == "true":
+ db_interface["port_security"] = 1
+ except KeyError:
+ raise NfvoException("Error. Invalid VNF descriptor at 'vnfd[{vnf}]':'vdu[{vdu}]':"
+ "'interface[{iface}]':'vnfd-connection-point-ref':'{cp}' is not present"
+ " at connection-point".format(
+ vnf=vnfd_id, vdu=vdu_id, iface=iface["name"],
+ cp=iface.get("vnfd-connection-point-ref")),
+ HTTP_Bad_Request)
+ elif iface.get("internal-connection-point-ref"):
+ try:
+ for vld in vnfd.get("internal-vld").itervalues():
+ for cp in vld.get("internal-connection-point").itervalues():
+ if cp.get("id-ref") == iface.get("internal-connection-point-ref"):
+ db_interface["net_id"] = net_id2uuid[vld.get("id")]
+ for cp_descriptor in vnfd_descriptor["connection-point"]:
+ if cp_descriptor["name"] == db_interface["external_name"]:
+ break
+ if str(cp_descriptor.get("port-security-enabled")).lower() == "false":
+ db_interface["port_security"] = 0
+ elif str(cp_descriptor.get("port-security-enabled")).lower() == "true":
+ db_interface["port_security"] = 1
+ break
+ except KeyError:
+ raise NfvoException("Error. Invalid VNF descriptor at 'vnfd[{vnf}]':'vdu[{vdu}]':"
+ "'interface[{iface}]':'vdu-internal-connection-point-ref':'{cp}' is not"
+ " referenced by any internal-vld".format(
+ vnf=vnfd_id, vdu=vdu_id, iface=iface["name"],
+ cp=iface.get("vdu-internal-connection-point-ref")),
+ HTTP_Bad_Request)
+ if iface.get("position") is not None:
+ db_interface["created_at"] = int(iface.get("position")) - 1000
+ db_interfaces.append(db_interface)
+
# table flavors
db_flavor = {
"name": get_str(vdu, "name", 250) + "-flv",
@@ -949,6 +1076,8 @@
numa = {}
if devices:
extended["devices"] = devices
+ if flavor_epa_interfaces:
+ numa["interfaces"] = flavor_epa_interfaces
if vdu.get("guest-epa"): # TODO or dedicated_int:
epa_vcpu_set = False
if vdu["guest-epa"].get("numa-node-policy"): # TODO or dedicated_int:
@@ -989,7 +1118,6 @@
extended_text = yaml.safe_dump(extended, default_flow_style=True, width=256)
db_flavor["extended"] = extended_text
# look if flavor exist
-
temp_flavor_dict = {'disk': db_flavor.get('disk', 1),
'ram': db_flavor.get('ram'),
'vcpus': db_flavor.get('vcpus'),
@@ -1005,113 +1133,6 @@
db_flavors.append(db_flavor)
db_vm["flavor_id"] = flavor_uuid
- # cloud-init
- boot_data = {}
- if vdu.get("cloud-init"):
- boot_data["user-data"] = str(vdu["cloud-init"])
- elif vdu.get("cloud-init-file"):
- # TODO Where this file content is present???
- # boot_data["user-data"] = vnfd_yang.files[vdu["cloud-init-file"]]
- boot_data["user-data"] = str(vdu["cloud-init-file"])
-
- if vdu.get("supplemental-boot-data"):
- if vdu["supplemental-boot-data"].get('boot-data-drive'):
- boot_data['boot-data-drive'] = True
- if vdu["supplemental-boot-data"].get('config-file'):
- om_cfgfile_list = list()
- for custom_config_file in vdu["supplemental-boot-data"]['config-file'].itervalues():
- # TODO Where this file content is present???
- cfg_source = str(custom_config_file["source"])
- om_cfgfile_list.append({"dest": custom_config_file["dest"],
- "content": cfg_source})
- boot_data['config-files'] = om_cfgfile_list
- if boot_data:
- db_vm["boot_data"] = yaml.safe_dump(boot_data, default_flow_style=True, width=256)
-
- db_vms.append(db_vm)
- db_vms_index += 1
-
- # table interfaces (internal/external interfaces)
- cp_name2iface_uuid = {}
- cp_name2vm_uuid = {}
- cp_name2db_interface = {}
- # for iface in chain(vdu.get("internal-interface").itervalues(), vdu.get("external-interface").itervalues()):
- for iface in vdu.get("interface").itervalues():
- iface_uuid = str(uuid4())
- uuid_list.append(iface_uuid)
- db_interface = {
- "uuid": iface_uuid,
- "internal_name": get_str(iface, "name", 255),
- "vm_id": vm_uuid,
- }
- if iface.get("virtual-interface").get("vpci"):
- db_interface["vpci"] = get_str(iface.get("virtual-interface"), "vpci", 12)
-
- if iface.get("virtual-interface").get("bandwidth"):
- bps = int(iface.get("virtual-interface").get("bandwidth"))
- db_interface["bw"] = bps/1000
-
- if iface.get("virtual-interface").get("type") == "OM-MGMT":
- db_interface["type"] = "mgmt"
- elif iface.get("virtual-interface").get("type") in ("VIRTIO", "E1000"):
- db_interface["type"] = "bridge"
- db_interface["model"] = get_str(iface.get("virtual-interface"), "type", 12)
- elif iface.get("virtual-interface").get("type") in ("SR-IOV", "PCI-PASSTHROUGH"):
- db_interface["type"] = "data"
- db_interface["model"] = get_str(iface.get("virtual-interface"), "type", 12)
- else:
- raise NfvoException("Error. Invalid VNF descriptor at 'vnfd[{}]':'vdu[{}]':'interface':'virtual"
- "-interface':'type':'{}'. Interface type is not supported".format(
- str(vnfd["id"])[:255], str(vdu["id"])[:255],
- iface.get("virtual-interface").get("type")),
- HTTP_Bad_Request)
-
- if iface.get("external-connection-point-ref"):
- try:
- cp = vnfd.get("connection-point")[iface.get("external-connection-point-ref")]
- db_interface["external_name"] = get_str(cp, "name", 255)
- cp_name2iface_uuid[db_interface["external_name"]] = iface_uuid
- cp_name2vm_uuid[db_interface["external_name"]] = vm_uuid
- cp_name2db_interface[db_interface["external_name"]] = db_interface
- for cp_descriptor in vnfd_descriptor["connection-point"]:
- if cp_descriptor["name"] == db_interface["external_name"]:
- break
- if str(cp_descriptor.get("port-security-enabled")).lower() == "false":
- db_interface["port_security"] = 0
- elif str(cp_descriptor.get("port-security-enabled")).lower() == "true":
- db_interface["port_security"] = 1
- except KeyError:
- raise NfvoException("Error. Invalid VNF descriptor at 'vnfd[{vnf}]':'vdu[{vdu}]':"
- "'interface[{iface}]':'vnfd-connection-point-ref':'{cp}' is not present"
- " at connection-point".format(
- vnf=vnfd["id"], vdu=vdu["id"], iface=iface["name"],
- cp=iface.get("vnfd-connection-point-ref")),
- HTTP_Bad_Request)
- elif iface.get("internal-connection-point-ref"):
- try:
- for vld in vnfd.get("internal-vld").itervalues():
- for cp in vld.get("internal-connection-point").itervalues():
- if cp.get("id-ref") == iface.get("internal-connection-point-ref"):
- db_interface["net_id"] = net_id2uuid[vld.get("id")]
- for cp_descriptor in vnfd_descriptor["connection-point"]:
- if cp_descriptor["name"] == db_interface["external_name"]:
- break
- if str(cp_descriptor.get("port-security-enabled")).lower() == "false":
- db_interface["port_security"] = 0
- elif str(cp_descriptor.get("port-security-enabled")).lower() == "true":
- db_interface["port_security"] = 1
- break
- except KeyError:
- raise NfvoException("Error. Invalid VNF descriptor at 'vnfd[{vnf}]':'vdu[{vdu}]':"
- "'interface[{iface}]':'vdu-internal-connection-point-ref':'{cp}' is not"
- " referenced by any internal-vld".format(
- vnf=vnfd["id"], vdu=vdu["id"], iface=iface["name"],
- cp=iface.get("vdu-internal-connection-point-ref")),
- HTTP_Bad_Request)
- if iface.get("position") is not None:
- db_interface["created_at"] = int(iface.get("position")) - 1000
- db_interfaces.append(db_interface)
-
# VNF affinity and antiaffinity
for pg in vnfd.get("placement-groups").itervalues():
pg_name = get_str(pg, "name", 255)
@@ -1120,7 +1141,7 @@
if vdu_id not in vdu_id2db_table_index:
raise NfvoException("Error. Invalid VNF descriptor at 'vnfd[{vnf}]':'placement-groups[{pg}]':"
"'member-vdus':'{vdu}'. Reference to a non-existing vdu".format(
- vnf=vnfd["id"], pg=pg_name, vdu=vdu_id),
+ vnf=vnfd_id, pg=pg_name, vdu=vdu_id),
HTTP_Bad_Request)
db_vms[vdu_id2db_table_index[vdu_id]]["availability_zone"] = pg_name
# TODO consider the case of isolation and not colocation
@@ -1129,19 +1150,24 @@
# VNF mgmt configuration
mgmt_access = {}
if vnfd["mgmt-interface"].get("vdu-id"):
- if vnfd["mgmt-interface"]["vdu-id"] not in vdu_id2uuid:
+ mgmt_vdu_id = get_str(vnfd["mgmt-interface"], "vdu-id", 255)
+ if mgmt_vdu_id not in vdu_id2uuid:
raise NfvoException("Error. Invalid VNF descriptor at 'vnfd[{vnf}]':'mgmt-interface':'vdu-id':"
"'{vdu}'. Reference to a non-existing vdu".format(
- vnf=vnfd["id"], vdu=vnfd["mgmt-interface"]["vdu-id"]),
+ vnf=vnfd_id, vdu=mgmt_vdu_id),
HTTP_Bad_Request)
mgmt_access["vm_id"] = vdu_id2uuid[vnfd["mgmt-interface"]["vdu-id"]]
+ # if only one cp is defined by this VDU, mark this interface as of type "mgmt"
+ if vdu_id2cp_name.get(mgmt_vdu_id):
+ cp_name2db_interface[vdu_id2cp_name[mgmt_vdu_id]]["type"] = "mgmt"
+
if vnfd["mgmt-interface"].get("ip-address"):
mgmt_access["ip-address"] = str(vnfd["mgmt-interface"].get("ip-address"))
if vnfd["mgmt-interface"].get("cp"):
if vnfd["mgmt-interface"]["cp"] not in cp_name2iface_uuid:
raise NfvoException("Error. Invalid VNF descriptor at 'vnfd[{vnf}]':'mgmt-interface':'cp':'{cp}'. "
"Reference to a non-existing connection-point".format(
- vnf=vnfd["id"], cp=vnfd["mgmt-interface"]["cp"]),
+ vnf=vnfd_id, cp=vnfd["mgmt-interface"]["cp"]),
HTTP_Bad_Request)
mgmt_access["vm_id"] = cp_name2vm_uuid[vnfd["mgmt-interface"]["cp"]]
mgmt_access["interface_id"] = cp_name2iface_uuid[vnfd["mgmt-interface"]["cp"]]
@@ -2173,7 +2199,8 @@
elif vld.get("provider-network").get("overlay-type") == "VLAN":
db_sce_net["type"] = "data"
else:
- db_sce_net["type"] = "bridge"
+ # later on it will be fixed to bridge or data depending on the type of interfaces attached to it
+ db_sce_net["type"] = None
db_sce_nets.append(db_sce_net)
# ip-profile, link db_ip_profile with db_sce_net
@@ -2197,7 +2224,7 @@
str(nsd["id"]), str(vld["id"]), str(iface["member-vnf-index-ref"])),
HTTP_Bad_Request)
- existing_ifaces = mydb.get_rows(SELECT=('i.uuid as uuid',),
+ existing_ifaces = mydb.get_rows(SELECT=('i.uuid as uuid', 'i.type as iface_type'),
FROM="interfaces as i join vms on i.vm_id=vms.uuid",
WHERE={'vnf_id': vnf_index2vnf_uuid[vnf_index],
'external_name': get_str(iface, "vnfd-connection-point-ref",
@@ -2210,6 +2237,8 @@
str(iface.get("vnfd-id-ref"))[:255]),
HTTP_Bad_Request)
interface_uuid = existing_ifaces[0]["uuid"]
+ if existing_ifaces[0]["iface_type"] == "data" and not db_sce_net["type"]:
+ db_sce_net["type"] = "data"
sce_interface_uuid = str(uuid4())
uuid_list.append(sce_net_uuid)
db_sce_interface = {
@@ -2220,6 +2249,8 @@
# "ip_address": #TODO
}
db_sce_interfaces.append(db_sce_interface)
+ if not db_sce_net["type"]:
+ db_sce_net["type"] = "bridge"
db_tables = [
{"scenarios": db_scenarios},
diff --git a/osm_ro/vimconn.py b/osm_ro/vimconn.py
index 1f60986..bdfcb15 100644
--- a/osm_ro/vimconn.py
+++ b/osm_ro/vimconn.py
@@ -487,9 +487,9 @@
the VLAN tag to be used. In case net_id is provided, the internal network vlan is used for tagging VF
'type': (mandatory) can be one of:
'virtual', in this case always connected to a network of type 'net_type=bridge'
- 'PF' (passthrough): depending on VIM capabilities it can be connected to a data/ptp network ot it
+ 'PCI-PASSTHROUGH' or 'PF' (passthrough): depending on VIM capabilities it can be connected to a data/ptp network ot it
can created unconnected
- 'VF' (SRIOV with VLAN tag): same as PF for network connectivity.
+ 'SR-IOV' or 'VF' (SRIOV with VLAN tag): same as PF for network connectivity.
'VFnotShared'(SRIOV without VLAN tag) same as PF for network connectivity. VF where no other VFs
are allocated on the same physical NIC
'bw': (optional) only for PF/VF/VFnotShared. Minimal Bandwidth required for the interface in GBPS
diff --git a/osm_ro/vimconn_aws.py b/osm_ro/vimconn_aws.py
index 0e1f573..12b2411 100644
--- a/osm_ro/vimconn_aws.py
+++ b/osm_ro/vimconn_aws.py
@@ -605,9 +605,9 @@
mac_address: (optional) mac address to assign to this interface
type: (mandatory) can be one of:
virtual, in this case always connected to a network of type 'net_type=bridge'
- PF - (passthrough): depending on VIM capabilities it can be connected to a data/ptp network ot it
- can created unconnected
- VF - (SRIOV with VLAN tag): same as PF for network connectivity.
+ 'PCI-PASSTHROUGH' or 'PF' (passthrough): depending on VIM capabilities it can be connected to a data/ptp network ot it
+ can created unconnected
+ 'SR-IOV' or 'VF' (SRIOV with VLAN tag): same as PF for network connectivity.
VFnotShared - (SRIOV without VLAN tag) same as PF for network connectivity. VF where no other VFs
are allocated on the same physical NIC
bw': (optional) only for PF/VF/VFnotShared. Minimal Bandwidth required for the interface in GBPS
diff --git a/osm_ro/vimconn_openstack.py b/osm_ro/vimconn_openstack.py
index c0f1b4d..7b1415b 100644
--- a/osm_ro/vimconn_openstack.py
+++ b/osm_ro/vimconn_openstack.py
@@ -947,7 +947,7 @@
model: interface model, ignored #TODO
mac_address: used for SR-IOV ifaces #TODO for other types
use: 'data', 'bridge', 'mgmt'
- type: 'virtual', 'PF', 'VF', 'VFnotShared'
+ type: 'virtual', 'PCI-PASSTHROUGH'('PF'), 'SR-IOV'('VF'), 'VFnotShared'
vim_id: filled/added by this function
floating_ip: True/False (or it can be None)
'cloud_config': (optional) dictionary with:
@@ -1001,7 +1001,7 @@
pass
# if "vpci" in net:
# metadata_vpci[ net["net_id"] ] = [[ net["vpci"], "" ]]
- elif net["type"]=="VF": # for VF
+ elif net["type"] == "VF" or net["type"] == "SR-IOV": # for VF
# if "vpci" in net:
# if "VF" not in metadata_vpci:
# metadata_vpci["VF"]=[]
@@ -1013,7 +1013,7 @@
port_dict["port_security_enabled"]=False
port_dict["provider_security_groups"]=[]
port_dict["security_groups"]=[]
- else: #For PT
+ else: # For PT PCI-PASSTHROUGH
# VIO specific Changes
# Current VIO release does not support port with type 'direct-physical'
# So no need to create virtual port in case of PCI-device.
diff --git a/osm_ro/vimconn_openvim.py b/osm_ro/vimconn_openvim.py
index b45edf6..b34fdf0 100644
--- a/osm_ro/vimconn_openvim.py
+++ b/osm_ro/vimconn_openvim.py
@@ -32,6 +32,7 @@
import json
import yaml
import logging
+import math
from openmano_schemas import id_schema, name_schema, nameshort_schema, description_schema, \
vlan1000_schema, integer0_schema
from jsonschema import validate as js_v, exceptions as js_e
@@ -599,6 +600,18 @@
for device in new_flavor_dict.get('extended', {}).get('devices', ()):
if 'image name' in device:
del device['image name']
+ numas = new_flavor_dict.get('extended', {}).get('numas')
+ if numas:
+ numa = numas[0]
+ # translate memory, cpus to EPA
+ if "cores" not in numa and "threads" not in numa and "paired-threads" not in numa:
+ numa["paired-threads"] = new_flavor_dict["vcpus"]
+ if "memory" not in numa:
+ numa["memory"] = int(math.ceil(new_flavor_dict["ram"]/1024.0))
+ for iface in numa.get("interfaces", ()):
+ if not iface.get("bandwidth"):
+ iface["bandwidth"] = "1 Mbps"
+
new_flavor_dict["name"] = flavor_data["name"][:64]
self._get_my_tenant()
payload_req = json.dumps({'flavor': new_flavor_dict})
@@ -786,7 +799,7 @@
def new_vminstance(self, name, description, start, image_id, flavor_id, net_list, cloud_config=None, disk_list=None,
availability_zone_index=None, availability_zone_list=None):
- '''Adds a VM instance to VIM
+ """Adds a VM instance to VIM
Params:
start: indicates if VM must start or boot in pause mode. Ignored
image_id,flavor_id: image and flavor uuid
@@ -797,7 +810,7 @@
model: interface model, virtio, e2000, ...
mac_address:
use: 'data', 'bridge', 'mgmt'
- type: 'virtual', 'PF', 'VF', 'VFnotShared'
+ type: 'virtual', 'PCI-PASSTHROUGH'('PF'), 'SR-IOV'('VF'), 'VFnotShared'
vim_id: filled/added by this function
#TODO ip, security groups
Returns a tuple with the instance identifier and created_items or raises an exception on error
@@ -805,7 +818,7 @@
the method delete_vminstance and action_vminstance. Can be used to store created ports, volumes, etc.
Format is vimconnector dependent, but do not use nested dictionaries and a value of None should be the same
as not present.
- '''
+ """
self.logger.debug("new_vminstance input: image='%s' flavor='%s' nics='%s'", image_id, flavor_id, str(net_list))
try:
self._get_my_tenant()
@@ -818,12 +831,25 @@
for net in net_list:
if not net.get("net_id"):
continue
- net_dict={'uuid': net["net_id"]}
- if net.get("type"): net_dict["type"] = net["type"]
- if net.get("name"): net_dict["name"] = net["name"]
- if net.get("vpci"): net_dict["vpci"] = net["vpci"]
- if net.get("model"): net_dict["model"] = net["model"]
- if net.get("mac_address"): net_dict["mac_address"] = net["mac_address"]
+ net_dict = {'uuid': net["net_id"]}
+ if net.get("type"):
+ if net["type"] == "SR-IOV":
+ net_dict["type"] = "VF"
+ elif net["type"] == "PCI-PASSTHROUGH":
+ net_dict["type"] = "PF"
+ else:
+ net_dict["type"] = net["type"]
+ if net.get("name"):
+ net_dict["name"] = net["name"]
+ if net.get("vpci"):
+ net_dict["vpci"] = net["vpci"]
+ if net.get("model"):
+ if net["model"] == "VIRTIO":
+ net_dict["model"] = "virtio"
+ else:
+ net_dict["model"] = net["model"]
+ if net.get("mac_address"):
+ net_dict["mac_address"] = net["mac_address"]
virtio_net_list.append(net_dict)
payload_dict={ "name": name[:64],
"description": description,
diff --git a/osm_ro/vimconn_vmware.py b/osm_ro/vimconn_vmware.py
index f99ef65..d1c3977 100644
--- a/osm_ro/vimconn_vmware.py
+++ b/osm_ro/vimconn_vmware.py
@@ -1388,9 +1388,9 @@
the VLAN tag to be used. In case net_id is provided, the internal network vlan is used for tagging VF
'type': (mandatory) can be one of:
'virtual', in this case always connected to a network of type 'net_type=bridge'
- 'PF' (passthrough): depending on VIM capabilities it can be connected to a data/ptp network ot it
+ 'PCI-PASSTHROUGH' or 'PF' (passthrough): depending on VIM capabilities it can be connected to a data/ptp network ot it
can created unconnected
- 'VF' (SRIOV with VLAN tag): same as PF for network connectivity.
+ 'SR-IOV' or 'VF' (SRIOV with VLAN tag): same as PF for network connectivity.
'VFnotShared'(SRIOV without VLAN tag) same as PF for network connectivity. VF where no other VFs
are allocated on the same physical NIC
'bw': (optional) only for PF/VF/VFnotShared. Minimal Bandwidth required for the interface in GBPS
@@ -1564,9 +1564,9 @@
reserve_memory = False
for net in net_list:
- if net["type"]=="PF":
+ if net["type"] == "PF" or net["type"] == "PCI-PASSTHROUGH":
pci_devices_info.append(net)
- elif (net["type"]=="VF" or net["type"]=="VFnotShared") and 'net_id'in net:
+ elif (net["type"] == "VF" or net["type"] == "SR-IOV" or net["type"] == "VFnotShared") and 'net_id'in net:
sriov_net_info.append(net)
#Add PCI
@@ -1670,7 +1670,7 @@
self.vca.block_until_completed(task)
# connect network to VM - with all DHCP by default
- type_list = ['PF','VF','VFnotShared']
+ type_list = ('PF', 'PCI-PASSTHROUGH', 'VF', 'SR-IOV', 'VFnotShared')
if 'type' in net and net['type'] not in type_list:
# fetching nic type from vnf
if 'model' in net:
@@ -4637,7 +4637,7 @@
for sriov_net in sriov_nets:
network_name = sriov_net.get('net_id')
dvs_portgr_name = self.create_dvPort_group(network_name)
- if sriov_net.get('type') == "VF":
+ if sriov_net.get('type') == "VF" or sriov_net.get('type') == "SR-IOV":
#add vlan ID ,Modify portgroup for vlan ID
self.configure_vlanID(content, vcenter_conect, network_name)
diff --git a/scenarios/examples/v3_2linux_sriov.yaml b/scenarios/examples/v3_2linux_sriov.yaml
new file mode 100644
index 0000000..74d1c3a
--- /dev/null
+++ b/scenarios/examples/v3_2linux_sriov.yaml
@@ -0,0 +1,73 @@
+nsd:nsd-catalog:
+ nsd:
+ - id: 2linux-sriov
+ name: 2linux_sriov
+ short-name: 2linux_sriov
+ description: Generated by OSM pacakage generator
+ vendor: OSM
+ version: '1.0'
+
+ # Place the logo as png in icons directory and provide the name here
+ logo: osm_2x.png
+
+ # Specify the VNFDs that are part of this NSD
+ constituent-vnfd:
+ # The member-vnf-index needs to be unique, starting from 1
+ # vnfd-id-ref is the id of the VNFD
+ # Multiple constituent VNFDs can be specified
+ - member-vnf-index: 1
+ vnfd-id-ref: linux-sriov
+ - member-vnf-index: 2
+ vnfd-id-ref: linux-sriov
+ scaling-group-descriptor:
+ - name: "scaling_cirros"
+ vnfd-member:
+ - count: 1
+ member-vnf-index-ref: 1
+ min-instance-count: 0
+ max-instance-count: 10
+ scaling-policy:
+ - scaling-type: "manual"
+ cooldown-time: 10
+ threshold-time: 10
+ name: manual_scale
+ vld:
+ # Networks for the VNFs
+ - id: mgmt
+ mgmt-network: 'true'
+ name: mgmt
+ type: ELAN
+ # vim-network-name: <update>
+ # provider-network:
+ # overlay-type: VLAN
+ # segmentation_id: <update>
+ vnfd-connection-point-ref:
+ # Specify the constituent VNFs
+ # member-vnf-index-ref - entry from constituent vnf
+ # vnfd-id-ref - VNFD id
+ # vnfd-connection-point-ref - connection point name in the VNFD
+ - member-vnf-index-ref: 1
+ vnfd-id-ref: linux-sriov
+ vnfd-connection-point-ref: eth0
+ - member-vnf-index-ref: 2
+ vnfd-id-ref: linux-sriov
+ vnfd-connection-point-ref: eth0
+ - id: sriov-vld
+ name: sriov_vld
+ type: ELAN
+ # vim-network-name: <update>
+ # provider-network:
+ # overlay-type: VLAN
+ # segmentation_id: <update>
+ vnfd-connection-point-ref:
+ # Specify the constituent VNFs
+ # member-vnf-index-ref - entry from constituent vnf
+ # vnfd-id-ref - VNFD id
+ # vnfd-connection-point-ref - connection point name in the VNFD
+ - member-vnf-index-ref: 1
+ vnfd-id-ref: linux-sriov
+ vnfd-connection-point-ref: sriov0
+ - member-vnf-index-ref: 2
+ vnfd-id-ref: linux-sriov
+ vnfd-connection-point-ref: sriov0
+
diff --git a/scenarios/examples/v3_3vdu_2vnf_nsd.yaml b/scenarios/examples/v3_3vdu_2vnf_nsd.yaml
index ffe8219..361805e 100644
--- a/scenarios/examples/v3_3vdu_2vnf_nsd.yaml
+++ b/scenarios/examples/v3_3vdu_2vnf_nsd.yaml
@@ -38,6 +38,7 @@
vld:
# Networks for the VNFs
- id: vld1
+ mgmt-network: 'true'
name: vld1-name
short-name: vld1-sname
type: ELAN
diff --git a/vnfs/examples/v3_3vdu_vnfd.yaml b/vnfs/examples/v3_3vdu_vnfd.yaml
index 203f40d..6d56e9d 100644
--- a/vnfs/examples/v3_3vdu_vnfd.yaml
+++ b/vnfs/examples/v3_3vdu_vnfd.yaml
@@ -39,7 +39,7 @@
type: EXTERNAL
position: 0
virtual-interface:
- type: OM-MGMT
+ type: VIRTIO
bandwidth: '0'
# vnfd-connection-point-ref: eth0
external-connection-point-ref: eth0
diff --git a/vnfs/examples/v3_linux_sriov.yaml b/vnfs/examples/v3_linux_sriov.yaml
new file mode 100644
index 0000000..78bdb83
--- /dev/null
+++ b/vnfs/examples/v3_linux_sriov.yaml
@@ -0,0 +1,53 @@
+vnfd:vnfd-catalog:
+ vnfd:
+ - id: linux-sriov
+ name: linux_sriov
+ short-name: linux_sriov
+ description: Simple VNF example with a ubuntu using SR-IOV
+ vendor: OSM
+ version: '1.0'
+
+ # Place the logo as png in icons directory and provide the name here
+ logo: cirros-64.png
+
+ # Management interface
+ mgmt-interface:
+ cp: eth0
+
+ # Atleast one VDU need to be specified
+ vdu:
+ - id: linux-sriov-VM
+ name: linux_sriov_VM
+ description: linux_sriov_VM
+ count: 1
+
+ # Flavour of the VM to be instantiated for the VDU
+ vm-flavor:
+ vcpu-count: 1
+ memory-mb: 2048
+ storage-gb: 20
+
+ # Image/checksum or image including the full path
+ image: ubuntu16.04
+ #checksum:
+
+ interface:
+ # Specify the external interfaces
+ - name: eth0
+ type: EXTERNAL
+ virtual-interface:
+ type: VIRTIO
+ external-connection-point-ref: eth0
+ - name: sriov0
+ type: EXTERNAL
+ virtual-interface:
+ type: SR-IOV
+ bandwidth: '0'
+ vpci: 0000:00:0b.0
+ external-connection-point-ref: sriov0
+ connection-point:
+ - name: eth0
+ type: VPORT
+ - name: sriov0
+ type: VPORT
+