Support of image name and checksum for each VDU/VNFC instead of the image location/path
Change-Id: I64c0659e64cb3c0d19dce2ce4fc2640c5700a1bd
Signed-off-by: garciadeblas <gerardo.garciadeblas@telefonica.com>
diff --git a/database_utils/migrate_mano_db.sh b/database_utils/migrate_mano_db.sh
index 447eb81..ae1ef15 100755
--- a/database_utils/migrate_mano_db.sh
+++ b/database_utils/migrate_mano_db.sh
@@ -183,6 +183,7 @@
[ $OPENMANO_VER_NUM -ge 4046 ] && DATABASE_TARGET_VER_NUM=12 #0.4.46=> 12
[ $OPENMANO_VER_NUM -ge 4047 ] && DATABASE_TARGET_VER_NUM=13 #0.4.47=> 13
[ $OPENMANO_VER_NUM -ge 4057 ] && DATABASE_TARGET_VER_NUM=14 #0.4.57=> 14
+[ $OPENMANO_VER_NUM -ge 4059 ] && DATABASE_TARGET_VER_NUM=15 #0.4.59=> 15
#TODO ... put next versions here
@@ -579,7 +580,7 @@
function upgrade_to_12(){
echo " upgrade database from version 0.11 to version 0.12"
echo " create ip_profiles table, with foreign keys to all nets tables, and add ip_address column to 'interfaces' and 'sce_interfaces'"
- echo "CREATE TABLE ip_profiles (
+ echo "CREATE TABLE IF NOT EXISTS ip_profiles (
id INT(11) NOT NULL AUTO_INCREMENT,
net_id VARCHAR(36) NULL DEFAULT NULL,
sce_net_id VARCHAR(36) NULL DEFAULT NULL,
@@ -641,6 +642,29 @@
echo "DELETE FROM schema_version WHERE version_int='14';" | $DBCMD || ! echo "ERROR. Aborted!" || exit -1
}
+function upgrade_to_15(){
+ echo " upgrade database from version 0.14 to version 0.15"
+ echo " add columns 'universal_name' and 'checksum' at table 'images', add unique index universal_name_checksum, and change location to allow NULL; change column 'image_path' in table 'vms' to allow NULL"
+ echo "ALTER TABLE images ADD COLUMN checksum VARCHAR(32) NULL DEFAULT NULL AFTER name;" | $DBCMD || ! echo "ERROR. Aborted!" || exit -1
+ echo "ALTER TABLE images ALTER location DROP DEFAULT;" | $DBCMD || ! echo "ERROR. Aborted!" || exit -1
+ echo "ALTER TABLE images ADD COLUMN universal_name VARCHAR(255) NULL AFTER name, CHANGE COLUMN location location VARCHAR(200) NULL AFTER checksum, ADD UNIQUE INDEX universal_name_checksum (universal_name, checksum);" | $DBCMD || ! echo "ERROR. Aborted!" || exit -1
+ echo "ALTER TABLE vms ALTER image_path DROP DEFAULT;" | $DBCMD || ! echo "ERROR. Aborted!" || exit -1
+ echo "ALTER TABLE vms CHANGE COLUMN image_path image_path VARCHAR(100) NULL COMMENT 'Path where the image of the VM is located' AFTER image_id;" | $DBCMD || ! echo "ERROR. Aborted!" || exit -1
+ echo "INSERT INTO schema_version (version_int, version, openmano_ver, comments, date) VALUES (15, '0.15', '0.4.59', 'add columns universal_name and checksum at table images, add unique index universal_name_checksum, and change location to allow NULL; change column image_path in table vms to allow NULL', '2016-09-27');" | $DBCMD || ! echo "ERROR. Aborted!" || exit -1
+}
+function downgrade_from_15(){
+ echo " downgrade database from version 0.15 to version 0.14"
+ echo " remove columns 'universal_name' and 'checksum' from table 'images', remove index universal_name_checksum, change location NOT NULL; change column 'image_path' in table 'vms' to NOT NULL"
+ echo "ALTER TABLE images DROP INDEX universal_name_checksum;" | $DBCMD || ! echo "ERROR. Aborted!" || exit -1
+ echo "ALTER TABLE images ALTER location DROP DEFAULT;" | $DBCMD || ! echo "ERROR. Aborted!" || exit -1
+ echo "ALTER TABLE images CHANGE COLUMN location location VARCHAR(200) NOT NULL AFTER checksum;" | $DBCMD || ! echo "ERROR. Aborted!" || exit -1
+ echo "ALTER TABLE images DROP COLUMN universal_name;" | $DBCMD || ! echo "ERROR. Aborted!" || exit -1
+ echo "ALTER TABLE images DROP COLUMN checksum;" | $DBCMD || ! echo "ERROR. Aborted!" || exit -1
+ echo "ALTER TABLE vms ALTER image_path DROP DEFAULT;" | $DBCMD || ! echo "ERROR. Aborted!" || exit -1
+ echo "ALTER TABLE vms CHANGE COLUMN image_path image_path VARCHAR(100) NOT NULL COMMENT 'Path where the image of the VM is located' AFTER image_id;" | $DBCMD || ! echo "ERROR. Aborted!" || exit -1
+ echo "DELETE FROM schema_version WHERE version_int='15';" | $DBCMD || ! echo "ERROR. Aborted!" || exit -1
+}
+
function upgrade_to_X(){
echo " change 'datacenter_nets'"
echo "ALTER TABLE datacenter_nets ADD COLUMN vim_tenant_id VARCHAR(36) NOT NULL AFTER datacenter_id, DROP INDEX name_datacenter_id, ADD UNIQUE INDEX name_datacenter_id (name, datacenter_id, vim_tenant_id);" | $DBCMD || ! echo "ERROR. Aborted!" || exit -1
diff --git a/nfvo.py b/nfvo.py
index dd3eb55..f681f5b 100644
--- a/nfvo.py
+++ b/nfvo.py
@@ -257,13 +257,17 @@
if only_create_at_vim:
image_mano_id = image_dict['uuid']
else:
- images = mydb.get_rows(FROM="images", WHERE={'location':image_dict['location'], 'metadata':image_dict['metadata']})
+ if image_dict['location'] is not None:
+ images = mydb.get_rows(FROM="images", WHERE={'location':image_dict['location'], 'metadata':image_dict['metadata']})
+ else:
+ images = mydb.get_rows(FROM="images", WHERE={'universal_name':image_dict['universal_name'], 'checksum':image_dict['checksum']})
if len(images)>=1:
image_mano_id = images[0]['uuid']
else:
#create image
temp_image_dict={'name':image_dict['name'], 'description':image_dict.get('description',None),
- 'location':image_dict['location'], 'metadata':image_dict.get('metadata',None)
+ 'location':image_dict['location'], 'metadata':image_dict.get('metadata',None),
+ 'universal_name':image_dict['universal_name'] , 'checksum':image_dict['checksum']
}
image_mano_id = mydb.new_row('images', temp_image_dict, add_uuid=True)
rollback_list.append({"where":"mano", "what":"image","uuid":image_mano_id})
@@ -274,7 +278,20 @@
image_db = mydb.get_rows(FROM="datacenters_images", WHERE={'datacenter_id':vim_id, 'image_id':image_mano_id})
#look at VIM if this image exist
try:
- image_vim_id = vim.get_image_id_from_path(image_dict['location'])
+ if image_dict['location'] is not None:
+ image_vim_id = vim.get_image_id_from_path(image_dict['location'])
+ else:
+ filter_dict={}
+ filter_dict['name']=image_dict['universal_name']
+ filter_dict['checksum']=image_dict['checksum']
+ vim_images = vim.get_image_list(filter_dict)
+ if len(vim_images) > 1:
+ raise NfvoException("More than one candidate VIM image found for filter: " + str(filter_dict), HTTP_Conflict)
+ elif len(vim_nets) == 0:
+ raise NfvoException("Image not found at VIM with filter: '%s'", str(filter_dict))
+ else:
+ image_vim_id = vim_images[0].id
+
except vimconn.vimconnNotFoundException as e:
#Create the image in VIM
try:
@@ -289,10 +306,10 @@
logger.warn("Error creating image at VIM: %s", str(e))
continue
except vimconn.vimconnException as e:
- logger.warn("Error contacting VIM to know if the image exist at VIM: %s", str(e))
+ logger.warn("Error contacting VIM to know if the image exists at VIM: %s", str(e))
image_vim_id = str(e)
continue
- #if reach here the image has been create or exist
+ #if we reach here, the image has been created or existed
if len(image_db)==0:
#add new vim_id at datacenters_images
mydb.new_row('datacenters_images', {'datacenter_id':vim_id, 'image_id':image_mano_id, 'vim_id': image_vim_id, 'created':image_created})
@@ -326,9 +343,14 @@
if 'extended' in flavor_dict and flavor_dict['extended']!=None:
dev_nb=0
for device in flavor_dict['extended'].get('devices',[]):
- if "image" not in device:
+ if "image" not in device or "image name" not in device:
continue
- image_dict={'location':device['image'], 'name':flavor_dict['name']+str(dev_nb)+"-img", 'description':flavor_dict.get('description')}
+ image_dict={}
+ image_dict['name']=device.get('image name',flavor_dict['name']+str(dev_nb)+"-img")
+ image_dict['universal_name']=device.get('image name')
+ image_dict['description']=flavor_dict['name']+str(dev_nb)+"-img"
+ image_dict['location']=device.get('image')
+ image_dict['checksum']=device.get('image checksum')
image_metadata_dict = device.get('image metadata', None)
image_metadata_str = None
if image_metadata_dict != None:
@@ -374,9 +396,14 @@
dev_nb=0
for index in range(0,len(devices_original)) :
device=devices_original[index]
- if "image" not in device:
+ if "image" not in device or "image name" not in device:
continue
- image_dict={'location':device['image'], 'name':flavor_dict['name']+str(dev_nb)+"-img", 'description':flavor_dict.get('description')}
+ image_dict={}
+ image_dict['name']=device.get('image name',flavor_dict['name']+str(dev_nb)+"-img")
+ image_dict['universal_name']=device.get('image name')
+ image_dict['description']=flavor_dict['name']+str(dev_nb)+"-img"
+ image_dict['location']=device.get('image')
+ image_dict['checksum']=device.get('image checksum')
image_metadata_dict = device.get('image metadata', None)
image_metadata_str = None
if image_metadata_dict != None:
@@ -472,7 +499,7 @@
#print "Flavor name: %s. Description: %s" % (VNFCitem["name"]+"-flv", VNFCitem["description"])
myflavorDict = {}
- myflavorDict["name"] = vnfc['name']+"-flv"
+ myflavorDict["name"] = vnfc['name']+"-flv" #Maybe we could rename the flavor by using the field "image name" if exists
myflavorDict["description"] = VNFCitem["description"]
myflavorDict["ram"] = vnfc.get("ram", 0)
myflavorDict["vcpus"] = vnfc.get("vcpus", 0)
@@ -520,7 +547,12 @@
#In case this integration is made, the VNFCDict might become a VNFClist.
for vnfc in vnf_descriptor['vnf']['VNFC']:
#print "Image name: %s. Description: %s" % (vnfc['name']+"-img", VNFCDict[vnfc['name']]['description'])
- image_dict={'location':vnfc['VNFC image'], 'name':vnfc['name']+"-img", 'description':VNFCDict[vnfc['name']]['description']}
+ image_dict={}
+ image_dict['name']=vnfc.get('image name',vnf_name+"-"+vnfc['name']+"-img")
+ image_dict['universal_name']=vnfc.get('image name')
+ image_dict['description']=vnfc.get('image name', VNFCDict[vnfc['name']]['description'])
+ image_dict['location']=vnfc.get('VNFC image')
+ image_dict['checksum']=vnfc.get('image checksum')
image_metadata_dict = vnfc.get('image metadata', None)
image_metadata_str = None
if image_metadata_dict is not None:
@@ -530,7 +562,7 @@
image_id = create_or_use_image(mydb, vims, image_dict, rollback_list)
#print "Image id for VNFC %s: %s" % (vnfc['name'],image_id)
VNFCDict[vnfc['name']]["image_id"] = image_id
- VNFCDict[vnfc['name']]["image_path"] = vnfc['VNFC image']
+ VNFCDict[vnfc['name']]["image_path"] = vnfc.get('VNFC image')
# Step 7. Storing the VNF descriptor in the repository
@@ -605,7 +637,7 @@
#print "Flavor name: %s. Description: %s" % (VNFCitem["name"]+"-flv", VNFCitem["description"])
myflavorDict = {}
- myflavorDict["name"] = vnfc['name']+"-flv"
+ myflavorDict["name"] = vnfc['name']+"-flv" #Maybe we could rename the flavor by using the field "image name" if exists
myflavorDict["description"] = VNFCitem["description"]
myflavorDict["ram"] = vnfc.get("ram", 0)
myflavorDict["vcpus"] = vnfc.get("vcpus", 0)
@@ -653,7 +685,12 @@
#In case this integration is made, the VNFCDict might become a VNFClist.
for vnfc in vnf_descriptor['vnf']['VNFC']:
#print "Image name: %s. Description: %s" % (vnfc['name']+"-img", VNFCDict[vnfc['name']]['description'])
- image_dict={'location':vnfc['VNFC image'], 'name':vnfc['name']+"-img", 'description':VNFCDict[vnfc['name']]['description']}
+ image_dict={}
+ image_dict['name']=vnfc.get('image name',vnf_name+"-"+vnfc['name']+"-img")
+ image_dict['universal_name']=vnfc.get('image name')
+ image_dict['description']=vnfc.get('image name', VNFCDict[vnfc['name']]['description'])
+ image_dict['location']=vnfc.get('VNFC image')
+ image_dict['checksum']=vnfc.get('image checksum')
image_metadata_dict = vnfc.get('image metadata', None)
image_metadata_str = None
if image_metadata_dict is not None:
@@ -663,7 +700,7 @@
image_id = create_or_use_image(mydb, vims, image_dict, rollback_list)
#print "Image id for VNFC %s: %s" % (vnfc['name'],image_id)
VNFCDict[vnfc['name']]["image_id"] = image_id
- VNFCDict[vnfc['name']]["image_path"] = vnfc['VNFC image']
+ VNFCDict[vnfc['name']]["image_path"] = vnfc.get('VNFC image')
# Step 7. Storing the VNF descriptor in the repository
diff --git a/openmano_schemas.py b/openmano_schemas.py
index 8af4682..e1fc2bd 100644
--- a/openmano_schemas.py
+++ b/openmano_schemas.py
@@ -54,6 +54,7 @@
schema_version_2={"type":"integer","minimum":2,"maximum":2}
#schema_version_string={"type":"string","enum": ["0.1", "2", "0.2", "3", "0.3"]}
log_level_schema={"type":"string", "enum":["DEBUG", "INFO", "WARNING","ERROR","CRITICAL"]}
+checksum_schema={"type":"string", "pattern":"^[0-9a-fA-F]{32}$"}
metadata_schema={
"type":"object",
@@ -461,6 +462,8 @@
"properties":{
"type":{"type":"string", "enum":["disk","cdrom","xml"] },
"image": path_schema,
+ "image name": name_schema,
+ "image checksum": checksum_schema,
"image metadata": metadata_schema,
"vpci":pci_schema,
"xml":xml_text_schema,
@@ -493,6 +496,8 @@
"name": name_schema,
"description": description_schema,
"VNFC image": {"oneOf": [path_schema, http_schema]},
+ "image name": name_schema,
+ "image checksum": checksum_schema,
"image metadata": metadata_schema,
#"cloud-config": cloud_config_schema, #common for all vnfs in the scenario
"processor": {
@@ -522,7 +527,11 @@
"devices": devices_schema
},
- "required": ["name", "VNFC image"],
+ "required": ["name"],
+ "oneOf": [
+ {"required": ["VNFC image"]},
+ {"required": ["image name"]}
+ ],
"additionalProperties": False
}
diff --git a/openmanod.py b/openmanod.py
index 2becccf..59a566d 100755
--- a/openmanod.py
+++ b/openmanod.py
@@ -33,9 +33,9 @@
'''
__author__="Alfonso Tierno, Gerardo Garcia, Pablo Montes"
__date__ ="$26-aug-2014 11:09:29$"
-__version__="0.4.58-r501"
+__version__="0.4.59-r502"
version_date="Sep 2016"
-database_version="0.14" #expected database schema version
+database_version="0.15" #expected database schema version
import httpserver
import time
diff --git a/test/basictest.sh b/test/basictest.sh
index 0d4fcea..11162dd 100755
--- a/test/basictest.sh
+++ b/test/basictest.sh
@@ -144,6 +144,7 @@
${DIRmano}/openmano vnf-delete -f linux_2VMs_v02 || echo "fail"
${DIRmano}/openmano vnf-delete -f dataplaneVNF_2VMs || echo "fail"
${DIRmano}/openmano vnf-delete -f dataplaneVNF_2VMs_v02 || echo "fail"
+ ${DIRmano}/openmano vnf-delete -f dataplaneVNF_2VMs_v02_withimagename || echo "fail"
${DIRmano}/openmano vnf-delete -f dataplaneVNF2 || echo "fail"
${DIRmano}/openmano vnf-delete -f dataplaneVNF3 || echo "fail"
${DIRmano}/openmano datacenter-detach TEST-dc || echo "fail"
@@ -187,7 +188,7 @@
[[ $? != 0 ]] && echo "FAIL" && echo " $result" && $_exit 1
echo OK
- for VNF in linux dataplaneVNF1 dataplaneVNF2 dataplaneVNF_2VMs dataplaneVNF_2VMs_v02 dataplaneVNF3 linux_2VMs_v02
+ for VNF in linux dataplaneVNF1 dataplaneVNF2 dataplaneVNF_2VMs dataplaneVNF_2VMs_v02 dataplaneVNF3 linux_2VMs_v02 dataplaneVNF_2VMs_v02_withimagename
do
printf "%-50s" "Creating VNF '${VNF}': "
result=`$DIRmano/openmano vnf-create $DIRmano/vnfs/examples/${VNF}.yaml`
diff --git a/vimconn.py b/vimconn.py
index e6e0421..7d68ac4 100644
--- a/vimconn.py
+++ b/vimconn.py
@@ -263,14 +263,22 @@
raise vimconnNotImplemented( "Should have implemented this" )
def get_image_id_from_path(self, path):
- '''Get the image id from image path in the VIM database'''
- '''Returns:
- 0,"Image not found" if there are no images with that path
- 1,image-id if there is one image with that path
- <0,message if there was an error (Image not found, error contacting VIM, more than 1 image with that path, etc.)
- '''
+ '''Get the image id from image path in the VIM database. Returns the image_id'''
raise vimconnNotImplemented( "Should have implemented this" )
+ def get_image_list(self, filter_dict={}):
+ '''Obtain tenant images from VIM
+ Filter_dict can be:
+ name: image name
+ id: image uuid
+ checksum: image checksum
+ location: image path
+ Returns the image list of dictionaries:
+ [{<the fields at Filter_dict plus some VIM specific>}, ...]
+ List can be empty
+ '''
+ raise vimconnNotImplemented( "Should have implemented this" )
+
def new_vminstance(self,name,description,start,image_id,flavor_id,net_list,cloud_config=None):
'''Adds a VM instance to VIM
Params:
diff --git a/vimconn_openstack.py b/vimconn_openstack.py
index 857b181..70f8c01 100644
--- a/vimconn_openstack.py
+++ b/vimconn_openstack.py
@@ -560,8 +560,7 @@
self._format_exception(e)
def get_image_id_from_path(self, path):
- '''Get the image id from image path in the VIM database. Returns the image_id
- '''
+ '''Get the image id from image path in the VIM database. Returns the image_id'''
try:
self._reload_connection()
images = self.nova.images.list()
@@ -572,6 +571,35 @@
except (ksExceptions.ClientException, nvExceptions.ClientException, gl1Exceptions.CommunicationError, ConnectionError) as e:
self._format_exception(e)
+ def get_image_list(self, filter_dict={}):
+ '''Obtain tenant images from VIM
+ Filter_dict can be:
+ id: image id
+ name: image name
+ checksum: image checksum
+ Returns the image list of dictionaries:
+ [{<the fields at Filter_dict plus some VIM specific>}, ...]
+ List can be empty
+ '''
+ self.logger.debug("Getting image list from VIM filter: '%s'", str(filter_dict))
+ try:
+ self._reload_connection()
+ filter_dict_os=filter_dict.copy()
+ #First we filter by the available filter fields: name, id. The others are removed.
+ filter_dict_os.pop('checksum',None)
+ image_list=self.nova.images.findall(**filter_dict_os)
+ if len(image_list)==0:
+ return []
+ #Then we filter by the rest of filter fields: checksum
+ filtered_list = []
+ for image in image_list:
+ image_dict=glance.images.get(image.id)
+ if image_dict['checksum']==filter_dict.get('checksum'):
+ filtered_list.append(image)
+ return filtered_list
+ except (ksExceptions.ClientException, nvExceptions.ClientException, gl1Exceptions.CommunicationError, ConnectionError) as e:
+ self._format_exception(e)
+
def new_vminstance(self,name,description,start,image_id,flavor_id,net_list,cloud_config=None):
'''Adds a VM instance to VIM
Params:
diff --git a/vimconn_openvim.py b/vimconn_openvim.py
index 9d42f9e..d415532 100644
--- a/vimconn_openvim.py
+++ b/vimconn_openvim.py
@@ -688,7 +688,7 @@
def get_image_id_from_path(self, path):
- '''Get the image id from image path in the VIM database'''
+ '''Get the image id from image path in the VIM database. Returns the image_id'''
try:
self._get_my_tenant()
url=self.url + '/' + self.tenant + '/images?path='+quote(path)
@@ -710,6 +710,36 @@
except (requests.exceptions.RequestException, js_e.ValidationError) as e:
self._format_request_exception(e)
+ def get_image_list(self, filter_dict={}):
+ '''Obtain tenant images from VIM
+ Filter_dict can be:
+ name: image name
+ id: image uuid
+ checksum: image checksum
+ location: image path
+ Returns the image list of dictionaries:
+ [{<the fields at Filter_dict plus some VIM specific>}, ...]
+ List can be empty
+ '''
+ try:
+ self._get_my_tenant()
+ filterquery=[]
+ filterquery_text=''
+ for k,v in filter_dict.iteritems():
+ filterquery.append(str(k)+'='+str(v))
+ if len(filterquery)>0:
+ filterquery_text='?'+ '&'.join(filterquery)
+ url = self.url+'/'+self.tenant+'/images'+filterquery_text
+ self.logger.info("Getting image list GET %s", url)
+ vim_response = requests.get(url, headers = self.headers_req)
+ self._check_http_request_response(vim_response)
+ self.logger.debug(vim_response.text)
+ #print json.dumps(vim_response.json(), indent=4)
+ response = vim_response.json()
+ return response['images']
+ except (requests.exceptions.RequestException, js_e.ValidationError) as e:
+ self._format_request_exception(e)
+
def new_vminstancefromJSON(self, vm_data):
'''Adds a VM instance to VIM'''
'''Returns the instance identifier'''
diff --git a/vnfs/examples/dataplaneVNF_2VMs_v02_withimagename.yaml b/vnfs/examples/dataplaneVNF_2VMs_v02_withimagename.yaml
new file mode 100644
index 0000000..0c54652
--- /dev/null
+++ b/vnfs/examples/dataplaneVNF_2VMs_v02_withimagename.yaml
@@ -0,0 +1,113 @@
+##
+# Copyright 2015 Telefónica Investigación y Desarrollo, S.A.U.
+# This file is part of openmano
+# All Rights Reserved.
+#
+# 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.
+#
+# For those usages not covered by the Apache License, Version 2.0 please
+# contact with: nfvlabs@tid.es
+##
+---
+schema_version: "0.2"
+vnf:
+ name: dataplaneVNF_2VMs_v02_withimagename
+ description: "Example of a dataplane VNF consisting of two VMs for data plane workloads with one internal network"
+ # class: parent # Optional. Used to organize VNFs
+ internal-connections:
+ - name: datanet
+ description: datanet
+ type: e-lan
+ implementation: underlay
+ ip-profile:
+ ip-version: IPv4
+ subnet-address: 192.168.1.0/24
+ gateway-address: 192.168.1.1
+ dns-address: 8.8.8.8
+ dhcp:
+ enabled: true
+ start-address: 192.168.1.100
+ count: 100
+ elements:
+ - VNFC: VNF_2VMs-VM1
+ local_iface_name: xe0
+ ip_address: 192.168.1.2
+ - VNFC: VNF_2VMs-VM2
+ local_iface_name: xe0
+ ip_address: 192.168.1.3
+ external-connections:
+ - name: control0
+ type: mgmt
+ VNFC: VNF_2VMs-VM1
+ local_iface_name: eth0
+ description: control interface VM1
+ - name: control1
+ type: mgmt
+ VNFC: VNF_2VMs-VM2
+ local_iface_name: eth0
+ description: control interface VM2
+ - name: in
+ type: data
+ VNFC: VNF_2VMs-VM1
+ local_iface_name: xe1
+ description: Dataplane interface input
+ - name: out
+ type: data
+ VNFC: VNF_2VMs-VM2
+ local_iface_name: xe1
+ description: Dataplane interface output
+ VNFC:
+ - name: VNF_2VMs-VM1
+ description: "Dataplane VM1 with 4 threads, 2 GB hugepages, 2 SR-IOV interface"
+ #Copy the image to a compute path and edit this path
+ image name: dataplaneVNF_2VMs-image
+ disk: 10
+ numas:
+ - paired-threads: 2 # "cores", "paired-threads", "threads"
+ memory: 2 # GBytes
+ interfaces:
+ - name: xe0
+ vpci: "0000:00:11.0"
+ dedicated: "no" # "yes"(passthrough), "no"(sriov with vlan tags), "yes:sriov"(sriovi, but exclusive and without vlan tag)
+ bandwidth: 1 Gbps
+ - name: xe1
+ vpci: "0000:00:12.0"
+ dedicated: "no"
+ bandwidth: 1 Gbps
+ bridge-ifaces:
+ - name: eth0
+ vpci: "0000:00:09.0"
+ bandwidth: 1 Mbps # Optional, informative only
+
+ - name: VNF_2VMs-VM2
+ description: "Dataplane VM1 with 2 threads, 2 GB hugepages, 2 SR-IOV interface"
+ #Copy the image to a compute path and edit this path
+ image name: dataplaneVNF_2VMs-image
+ disk: 10
+ numas:
+ - paired-threads: 1 # "cores", "paired-threads", "threads"
+ memory: 2 # GBytes
+ interfaces:
+ - name: xe0
+ vpci: "0000:00:11.0"
+ dedicated: "no" # "yes"(passthrough), "no"(sriov with vlan tags), "yes:sriov"(sriovi, but exclusive and without vlan tag)
+ bandwidth: 1 Gbps
+ - name: xe1
+ vpci: "0000:00:12.0"
+ dedicated: "no"
+ bandwidth: 1 Gbps
+ bridge-ifaces:
+ - name: eth0
+ vpci: "0000:00:09.0"
+ bandwidth: 1 Mbps # Optional, informative only
+