RM="--remove-files"
DEBUG=false
+ARCHIVE=false
+CREATE_NSD=false
+VENDOR='OSM'
+INTF_TYPE='VIRTIO'
+VCPU=2
+MEMORY=4096
+STORAGE=10
+CLOUD_INIT='#cloud-config '
+INTERFACES=1
+
function usage() {
cat <<EOF
Usage:
- $SCRIPTNAME [-t <type>] [-N] [-c] [base-directory] <package-dir>
+ $SCRIPTNAME [-t <type>] [-N] [-c] [base-directory] <package-name>
-h|--help : show this message
-d|--destination-dir <destination directory>: Directory to create the
archived file.
+ Default is base-directory
-N|--no-remove-files : Do not remove the package files after creating
archive
- -c|--create-folder : Create folder with the structure for the
- package type using the base-dir and package-dir
- and a descriptor template
+ Options specifc for create descriptor:
+
+ -c|--create-folder : Create folder with the structure for the
+ package type using the base-dir and package-dir
+ and a descriptor template
+
+ -a|--archive: Create package for the descriptor
+
+ --nsd : Generate NSD descriptor package also.
+
+ --vendor : Vendor name for descriptor. Default OSM
+
+ --interface-type : Interface type [VIRTIO|SR-IOV|PCI-PASSTHROUGH|E1000|OM-MGMT]
+ Default VIRTIO
+
+ VM Flavour options:
+
+ --vcpu : Virtual CPU count. Default 2
+
+ --memory : Memory for VM in MB. Default 4096MB
+
+ --storage : Storage size for VM in GB. Default 10GB
+
+ VDU Parameters:
+
+ --image : Location URI of the image
+
+ --cloud-init-file : Cloud init file
- -v| --verbose : Generate logs
+ --cloud-init : Cloud init script. Will be ignored if
+ cloud-init-file is specified
+
+ --interfaces : Number of external interfaces. Default 1.
+
+ End of create descriptor specific options
+
+ -v| --verbose : Generate progress details
-n| --dry-run : Validate the package dir
if destination directory is not specified.
Default is current directory
- package-dir : The descriptor name and directory
+ package-name : The descriptor name (full path if base-dir not specified)
EOF
}
+CP_TYPE='VPORT'
+function get_cp_type() {
+ case ${INTF_TYPE} in
+ VIRTIO ) CP_TYPE='VPORT';;
+ SR-IOV ) CP_TYPE='VPORT';;
+ PCI-PASSTHROUGH ) CP_TYPE='VPORT';;
+ OM-MGMT ) CP_TYPE='VPORT';;
+ E1000 ) CP_TYPE='VPORT';;
+ * ) echo "ERROR: Unknown interface type ${INTF_TYPE}"; exit 1;;
+ esac
+}
+
+# Get pci number starting from 0x0a
+get_pci() {
+ printf '%02x' $((10 + $1)) | tr '[:upper:]' '[:lower:]'
+}
+
function write_vnfd_tmpl() {
name=$(basename $1)
- desc_file="${name}_vnfd.yaml"
+ desc_file="${name}.yaml"
cat >$desc_file <<EOF
-# Only one VNFD per descriptor package is supported
-# Update the <update> tag with correct values
-# Update or remove <update, optional> tags
vnfd:vnfd-catalog:
vnfd:
- id: ${name}
name: ${name}
short-name: ${name}
- description: ${name}
+ description: Generated by OSM pacakage generator
+ vendor: ${VENDOR}
+ version: '1.0'
# Place the logo as png in icons directory and provide the name here
- logo: <update, optional>
-
- # This is an optional section and can be removed
- vnf-configuration:
- config-attributes:
- config-delay: '0'
- config-priority: '1'
-
- # Specify the config method
- # Remove this section if the VNF does not use a config method
- juju:
- charm: <update>
-
- # config-primitive specifies the config and actions for the VNF/charm
- # This is an optional section
- config-primitive:
- # If there are no config to be set, remove this section
- - name: config
- # There can be multiple parameter sections
- # The name and type should be same as VNF/charm specification
- parameter:
- - name: <update>
- data-type: STRING
- mandatory: <true|false>
- default-value: <update>
-
- # If there are no actions specified at VNF level, remove this section
- # Multiple action sections can be specified
- # The name should be the name of the action
- - name: <update, optional>
- # There can be multiple parameter sections
- # The name and type should be same as charm specification
- parameter:
- - name: <update, optional>
- data-type: STRING
- mandatory: <true|false>
-
- # Any config or action that need to be executed when VNF comes up
- # This is an optional section
- initial-config-primitive:
- - name: config
- # Any config to be set when VNF comes up
- # For charm normally the VNF management IP need to be set
- # in one of the config parameters
- # Sepcifying the value a <rw_mgmt_ip> will cause the MANO
- # to replace this with the management ip of VNF when it is
- # instantiated
- parameter:
- - name: <update>
- value: <rw_mgmt_ip>
- seq: '1'
+ # logo: <update, optional>
+ # Management interface
mgmt-interface:
- # This should be id of one of the VDUs specified for this VNF
vdu-id: ${name}-VM
- port: <update, optional>
-
- connection-point:
- # Specify the connection points from VDU
- # Can specify multiple connection points here
- - name: eth0
- type: VPORT
- - name: eth1
- type: VPORT
# Atleast one VDU need to be specified
vdu:
- id: ${name}-VM
name: ${name}-VM
description: ${name}-VM
-
- # Image including the full path
- image: <update>
+ count: 1
# Flavour of the VM to be instantiated for the VDU
vm-flavor:
- memory-mb: '4096'
- storage-gb: '10'
- vcpu-count: '2'
+ vcpu-count: ${VCPU}
+ memory-mb: ${MEMORY}
+ storage-gb: ${STORAGE}
+ # Image including the full path
+ image: '${IMAGE}'
+
+EOF
+
+ # Add the cloud init file or script
+ if [[ -n ${CLOUD_INIT_FILE} ]]; then
+ cif=$(basename ${CLOUD_INIT_FILE})
+ cat >>$desc_file <<EOF
+ # Cloud init file
+ cloud-init-file: '${cif}'
+EOF
+ else
+ cat >>$desc_file <<EOF
+ # Cloud init to use
+ cloud-init: '${CLOUD_INIT}'
+EOF
+ fi
+
+ # Add external interfaces
+ cat >>$desc_file <<EOF
external-interface:
# Specify the external interfaces
# There can be multiple interfaces defined
- - name: eth0
- virtual-interface:
- bandwidth: '0'
- type: VIRTIO
- vpci: 0000:00:0a.0
- vnfd-connection-point-ref: eth0
- - name: eth1
+EOF
+
+ # Add external interfaces
+ for i in `seq 1 ${INTERFACES}`; do
+ eth=$(($i - 1))
+ pci=$(get_pci $eth)
+ cat >>$desc_file <<EOF
+ - name: eth${eth}
virtual-interface:
+ type: ${INTF_TYPE}
bandwidth: '0'
- type: OM-MGMT
- vpci: 0000:00:0b.0
- vnfd-connection-point-ref: eth1
-
- # Mgmt vpci, match with the specification in the
- # external interface for mgmt
- mgmt-vpci: 0000:00:0a.0
-
- # Specify EPA parameters
- # This section is optional
- guest-epa:
- cpu-pinning-policy: DEDICATED
- cpu-thread-pinning-policy: PREFER
- mempage-size: LARGE
- numa-node-policy:
- mem-policy: STRICT
- node:
- - id: '0'
- paired-threads:
- num-paired-threads: '1'
- node-cnt: '1'
+ vpci: 0000:00:${pci}.0
+ vnfd-connection-point-ref: eth${eth}
+EOF
+ done
+
+ # Add connection points
+ cat >>$desc_file <<EOF
+
+ connection-point:
+EOF
+ for i in `seq 1 ${INTERFACES}`; do
+ eth=$(($i - 1))
+ cat >>$desc_file <<EOF
+ - name: eth${eth}
+ type: ${CP_TYPE}
EOF
+ done
if [ $VERBOSE == true ]; then
echo "INFO: Created $desc_file"
function write_nsd_tmpl() {
name=$(basename $1)
- desc_file="${name}_nsd.yaml"
+ vnfd=$2
+ desc_file="${name}.yaml"
cat >$desc_file <<EOF
-# Only one NSD per descriptor package is supported
-# Update the <update> tag with correct values
-# Update or remove <update, optional> tags
nsd:nsd-catalog:
nsd:
- id: ${name}
name: ${name}
short-name: ${name}
- description: ${name}
+ description: Generated by OSM pacakage generator
+ vendor: ${VENDOR}
+ version: '1.0'
# Place the logo as png in icons directory and provide the name here
- logo: <update, optional>
+ # logo: <update, optional>
# 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: <update>
- vnfd-id-ref: <update>
+ - member-vnf-index: 1
+ vnfd-id-ref: ${vnfd}
+
+EOF
+ cat >>$desc_file <<EOF
vld:
- # Management network for the VNFs
- - id: management
- name: management
- provider-network:
- overlay-type: VLAN
- physical-network: <update>
- type: ELAN
- vnfd-connection-point-ref:
- # Specify all 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-connection-point-ref: <update>
- vnfd-id-ref: <update>
- - member-vnf-index-ref: '2'
- vnfd-connection-point-ref: <update>
- vnfd-id-ref: <update>
-
- # Addtional netowrk can be specified for data, etc
- - id: <update>
- name: <update>
- type: ELAN
- provider-network:
- overlay-type: VLAN
- physical-network: <update>
- vnfd-connection-point-ref:
- - member-vnf-index-ref: <update>
- vnfd-connection-point-ref: <update>
- vnfd-id-ref: <update>
-
- # NS level configuration primitive
- # This section is optional
- config-primitive:
- - name: <update>
- # List of parameters, optional
- parameter:
- - name: <update>
- data-type: string
- default-value: <update>
- mandatory: <true|false>
-
- # List of parameters grouped by name
- # optional section
- parameter-group:
- - mandatory: <true|false>
- name: <update>
- parameter:
- - name: <update>
- data-type: integer
- default-value: <update>
- hidden: <true|false>
- mandatory: <true|false>
-
- # Script based NS level configuration
- user-defined-script: <update>
+ # Networks for the VNFs
+EOF
+
+ for i in `seq 1 ${INTERFACES}`; do
+ eth=$(($i - 1))
+ cat >>$desc_file <<EOF
+ - id: ${name}_vld${i}
+ name: ${name}_vld${i}
+ type: ELAN
+ provider-network:
+ overlay-type: VLAN
+ physical-network: <update>
+ 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
+ - nsd:member-vnf-index-ref: 1
+ nsd:vnfd-id-ref: ${vnfd}
+ # Validate the entry below
+ nsd:vnfd-connection-point-ref: eth${eth}
EOF
+ done
if [ $VERBOSE == true ]; then
echo "INFO: Created $desc_file"
fi
}
-OPTS=`getopt -o vhnt:d:cN --long verbose,dry-run,help,package-type:,destination-dir,create-folder,no-remove-files,debug -n $SCRIPTNAME -- "$@"`
-
-if [ $? != 0 ] ; then
- echo "ERROR: Failed parsing options ($?)." >&2
- usage
- exit 1
-fi
-
-echo "$OPTS"
-eval set -- "$OPTS"
-
cur_dir=`pwd`
# Check if the array contains a specific value
fi
}
-function get_expr(){
- # First argument is to specify if this is a negative match or match
- # Rest are filename expressions without extension
- #
-
- local regex=" "
- local n=$1
- local neg="${1}"
- for ((i=2;i <= $#;i++)); do
- if [ $i -eq 2 ]; then
- if [ $neg == true ]; then
- subexpr='! -name'
- else
- subexpr='-name'
- fi
- else
- if [ $neg == true ]; then
- subexpr=' -a ! -name'
- else
- subexpr=' -o -name'
- fi
- fi
-
- for extn in ${DESC_EXTN[$@]}; do
- regex="$regex $subexpr ${!i}.$extn"
- done
- done
-
- if [ $VERBOSE == true ]; then
- echo "INFO: Generate expression: $expr"
- fi
-
- echo "$expr"
-}
-
function get_expr(){
# First argument is to specify if this is a negative match or not
# Rest are filename expressions without extension
echo "$regex"
}
+function generate_package(){
+ type=$1
+ name="${2}_${type}"
+ vnfd="${2}_vnfd" # Required for NSD
+ dest_dir=$3
+
+ dir="${dest_dir}/${name}"
+
+ # Create the folders for the descriptor
+ if [ $VERBOSE == true ]; then
+ echo "INFO: Creating folders for $PKG in $dest_dir"
+ fi
+
+ # Remove any existing directory
+ if [ -d $dir ]; then
+ rm -rf $dir >/dev/null 2>&1
+ fi
+
+ mkdir -p $dir && cd $dir
+ if [ $? -ne 0 ]; then
+ rc=$?
+ echo "ERROR: creating directory $dir ($rc)" >&2
+ exit $rc
+ fi
+
+ if [ $type == 'nsd' ]; then
+ folders=("${NSD_FOLDERS[@]}")
+ else
+ folders=("${VNFD_FOLDERS[@]}")
+ fi
+
+ for d in ${folders[@]}; do
+ mkdir -p $dir/$d
+ if [ $? -ne 0 ]; then
+ rc=$?
+ echo "ERROR: creating directory $dir/$d ($rc)" >&2
+ exit $rc
+ fi
+ if [ $VERBOSE == true ]; then
+ echo "Created folder $d in $dir"
+ fi
+ done
+
+ if [ $VERBOSE == true ]; then
+ echo "INFO: Created folders for in $dir"
+ fi
+
+ # Write a descriptor template file
+ if [ $type == 'vnfd' ]; then
+
+ # Copy cloud init file to correct folder
+ if [[ -n ${CLOUD_INIT_FILE} ]]; then
+ if [[ -e ${CLOUD_INIT_FILE} ]]; then
+ cp ${CLOUD_INIT_FILE} $dir/cloud_init
+ else
+ echo "ERROR: Unable to find cloud-init-file ${CLOUD_INIT_FILE}"
+ exit 1
+ fi
+ fi
+
+ write_vnfd_tmpl $dir
+ else
+ write_nsd_tmpl $dir $vnfd
+ fi
+
+ if [ $ARCHIVE == true ]; then
+ # Create archive of the package
+ cd $dest_dir
+ if [ $VERBOSE == true ]; then
+ tar zcvf ${name}.tar.gz ${name}
+ echo "Created package ${name}.tar.gz in $dest_dir"
+ else
+ tar zcvf ${name}.tar.gz ${name} >/dev/null 2>&1
+ fi
+
+ if [ $? -ne 0 ]; then
+ echo "ERROR: Creating archive for ${name} in $dest_dir" >&2
+ exit 1
+ fi
+
+ echo "$dest_dir/${name}.tar.gz" >&2
+
+ if [ $RM == true ]; then
+ rm -rf ${name}
+ fi
+ fi
+}
+
+OPTS=`getopt -o vhnt:d:caN --long verbose,dry-run,help,package-type:,destination-dir,create-folder,no-remove-files,archive,nsd,vendor:,interface-type:,vcpu:,memory:,storage:,image:,cloud-init-file:,cloud-init:,interfaces:,debug -n $SCRIPTNAME -- "$@"`
+
+if [ $? != 0 ] ; then
+ echo "ERROR: Failed parsing options ($?)." >&2
+ usage
+ exit 1
+fi
+
+echo "$OPTS"
+eval set -- "$OPTS >/dev/null 2>&1"
+
while true; do
case "$1" in
-v | --verbose ) VERBOSE=true; shift ;;
-d | --destination-dir ) DEST_DIR=$2; shift; shift;;
-c | --create-folder ) CREATE=true; shift;;
-N | --no-remove-files ) RM=''; shift;;
+ -a | --archive ) ARCHIVE=true; shift;;
+ --nsd ) CREATE_NSD=true; shift;;
+ --vendor ) VENDOR=$2; shift; shift;;
+ --interface-type ) INTF_TYPE=$2; shift; shift;;
+ --vcpu ) VCPU=$2; shift; shift;;
+ --memory ) MEMORY=$2; shift; shift;;
+ --storage ) STORAGE=$2; shift; shift;;
+ --image ) IMAGE=$2; shift; shift;;
+ --cloud-init ) CLOUD_INIT=$2; shift; shift;;
+ --cloud-init-file ) CLOUD_INIT_FILE=$2; shift; shift;;
+ --interfaces ) INTERFACES=$2; shift; shift;;
--debug ) DEBUG=true; shift;;
-- ) shift; break ;;
* ) break ;;
echo "INFO: Using package: $PKG"
fi
-if [ -z "$PKG" ]; then
- echo "ERROR: Need to specify the package-dir" >&2
+if [[ -z "$PKG" ]]; then
+ echo "ERROR: Need to specify the package name" >&2
usage >&2
exit 1
fi
cd $BASE_DIR
if [ $? -ne 0 ]; then
- echo "ERROR: Unable to change to base directory $BASE_DIR!" >&2
- exit 1
+ if [ $CREATE == true ]; then
+ mkdir -p $BASE_DIR
+ if [ $? -ne 0 ]; then
+ echo "ERROR: Unable to create base directory $BASE_DIR" >&2
+ exit 1
+ fi
+ cd $BASE_DIR
+ else
+ echo "ERROR: Unable to change to base directory $BASE_DIR!" >&2
+ exit 1
+ fi
fi
# Get full base dir path
BASE_DIR=`pwd`
cd $cur_dir
-if [ -z $DEST_DIR ]; then
+if [[ -z $DEST_DIR ]]; then
DEST_DIR=$BASE_DIR # Default to base directory
fi
rm -f $CHKSUM
# Check if the descriptor file is present
- if [ -z $TYPE ]; then
+ if [[ -z $TYPE ]]; then
# Desc type not specified, look for the desc file and guess the type
# Required for backward compatibility
for ty in ${DESC_TYPES[@]}; do
re=$(get_expr false "$ty" "*_$ty" "*_${ty}_*")
desc=$(find * -maxdepth 0 -type f $re 2>/dev/null)
- if [ -z $desc ] || [ ${#desc[@]} -eq 0 ]; then
+ if [[ -z $desc ]] || [ ${#desc[@]} -eq 0 ]; then
# Check the vnfd|nsd folder
if [ ! -d $ty ]; then
continue
fi
re=$(get_expr false "*")
desc=$(find $ty/* -maxdepth 0 -type f $re 2>/dev/null)
- if [ -z $desc ] || [ ${#desc[@]} -eq 0 ]; then
+ if [[ -z $desc ]] || [ ${#desc[@]} -eq 0 ]; then
continue
elif [ ${#desc[@]} -gt 1 ]; then
echo "ERROR: Found multiple descriptor files: ${desc[@]}" >&2
break
done
- if [ -z $TYPE ]; then
+ if [[ -z $TYPE ]]; then
echo "ERROR: Unable to determine the descriptor type!" >&2
exit 1
fi
re=$(get_expr false "$TYPE" "*_${TYPE}" "*_${TYPE}_*")
desc=$(find * -maxdepth 0 -type f $re 2>/dev/null)
- if [ -z $desc ] || [ ${#desc[@]} -eq 0 ]; then
+ if [[ -z $desc ]] || [ ${#desc[@]} -eq 0 ]; then
# Check if it is under vnfd/nsd subdirectory
# Backward compatibility support
re=$(get_expr false "*")
desc=$(find $TYPE/* -maxdepth 0 -type f $re 2>/dev/null)
- if [ -z $desc ] || [ ${#desc[@]} -eq 0 ]; then
+ if [[ -z $desc ]] || [ ${#desc[@]} -eq 0 ]; then
echo "ERROR: Did not find descriptor file of type $TYPE" \
" in $dir" >&2
exit 1
add_chksum $file
done
fi
- elif [ -z $desc_sub_dir ] || [ $d != $desc_sub_dir ]; then
+ elif [[ -z $desc_sub_dir ]] || [ $d != $desc_sub_dir ]; then
echo "WARN: $d is not part of standard folders " \
"for descriptor type $TYPE in $PKG"
fi
fi
fi
else
- # Create the folders for the descriptor
- if [ $VERBOSE == true ]; then
- echo "INFO: Creating folders for $PKG in $dir"
- fi
-
# Create, default to VNFD if no type is defined
- if [ -z $TYPE ]; then
+ if [[ -z $TYPE ]]; then
TYPE=vnfd
- echo "WARNING: Defaulting to descriptor type $TYPE"
- fi
-
- mkdir -p $dir && cd $dir
- if [ $? -ne 0 ]; then
- rc=$?
- echo "ERROR: creating directory $dir ($rc)" >&2
- exit $rc
- fi
-
- if [ $TYPE == 'nsd' ]; then
- folders=("${NSD_FOLDERS[@]}")
- else
- folders=("${VNFD_FOLDERS[@]}")
- fi
-
- for d in ${folders[@]}; do
- mkdir -p $dir/$d
- if [ $? -ne 0 ]; then
- rc=$?
- echo "ERROR: creating directory $dir/$d ($rc)" >&2
- exit $rc
- fi
if [ $VERBOSE == true ]; then
- echo "Created folder $d in $dir"
+ echo "WARNING: Defaulting to descriptor type $TYPE"
fi
- done
-
- if [ $VERBOSE == true ]; then
- echo "INFO: Created folders for in $dir"
fi
- # Write a descriptor template file
if [ $TYPE == 'vnfd' ]; then
- write_vnfd_tmpl $dir
- else
- write_nsd_tmpl $dir
- # write_nsd_config_tmpl $dir
+ if [[ -z $IMAGE ]]; then
+ echo "ERROR: Image file need to be specified for VNF"
+ exit 1
+ fi
+ generate_package vnfd $PKG $DEST_DIR
+ fi
+
+ if [ $TYPE == 'nsd' -o $CREATE_NSD == true ]; then
+ generate_package nsd $PKG $DEST_DIR
fi
fi