3 ############################################################################
4 # Copyright 2016 RIFT.io Inc #
6 # Licensed under the Apache License, Version 2.0 (the "License"); #
7 # you may not use this file except in compliance with the License. #
8 # You may obtain a copy of the License at #
10 # http://www.apache.org/licenses/LICENSE-2.0 #
12 # Unless required by applicable law or agreed to in writing, software #
13 # distributed under the License is distributed on an "AS IS" BASIS, #
14 # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. #
15 # See the License for the specific language governing permissions and #
16 # limitations under the License. #
17 ############################################################################
20 # This shell script is used to create a descriptor package
21 # The main functions of this script include:
22 # - Generate checksums.txt file
23 # - Generate a tar.gz file
24 # This script can be used to create the required folders for
25 # a descriptor package and a template descriptor
27 # Usage: generate_descriptor_pkg.sh <base-directory> <package-directory>
29 # Descriptor names should be
30 # - (nsd|vnfd).(yaml|yml|json|xml)
31 # - *_(nsd|vnfd).(yaml|yml|json|xml)
32 # - *_(nsd|vnfd)_*.(yaml|yml|json|xml)
33 # - (nsd|vnfd)/*.(yaml|yml|json|xml)
36 SCRIPTNAME
=`basename $0`
38 # From https://osm.etsi.org/wikipub/index.php/Release_0_Data_Model_Details
39 # Supported folders for VNFD
40 # cloud_init - Rel 4.3, not yet part of OSM
41 VNFD_FOLDERS
=(images scripts icons charms cloud_init
)
43 # Supported folders for NSD
44 # OSM document specifies (ns|vnf)-config folder, while Rel 4.3
45 # is using (ns|vnf)_config.
46 NSD_FOLDERS
=(scripts icons ns_config vnf_config
)
48 # Other files allowed in the descriptor base directory
49 ALLOWED_FILES
=(README
)
52 DESC_EXTN
=(yml yaml json xml
)
53 CHKSUM
='checksums.txt'
64 $SCRIPTNAME [-t <type>] [-N] [-c] [base-directory] <package-dir>
66 -h|--help : show this message
68 -t|--package-type <nsd|vnfd> : Descriptor package type
69 is NSD or VNFD. Script will try to
70 determine the type if not provided.
71 Default is vnfd for create-folders.
73 -d|--destination-dir <destination directory>: Directory to create the
76 -N|--no-remove-files : Do not remove the package files after creating
79 -c|--create-folder : Create folder with the structure for the
80 package type using the base-dir and package-dir
81 and a descriptor template
83 -v| --verbose : Generate logs
85 -n| --dry-run : Validate the package dir
87 base-dir : Directory where the archive file or folders are created,
88 if destination directory is not specified.
89 Default is current directory
91 package-dir : The descriptor name and directory
95 function write_vnfd_tmpl
() {
97 desc_file
="${name}_vnfd.yaml"
100 # Only one VNFD per descriptor package is supported
101 # Update the <update> tag with correct values
102 # Update or remove <update, optional> tags
110 # Place the logo as png in icons directory and provide the name here
111 logo: <update, optional>
113 # This is an optional section and can be removed
119 # Specify the config method
120 # Remove this section if the VNF does not use a config method
124 # config-primitive specifies the config and actions for the VNF/charm
125 # This is an optional section
127 # If there are no config to be set, remove this section
129 # There can be multiple parameter sections
130 # The name and type should be same as VNF/charm specification
134 mandatory: <true|false>
135 default-value: <update>
137 # If there are no actions specified at VNF level, remove this section
138 # Multiple action sections can be specified
139 # The name should be the name of the action
140 - name: <update, optional>
141 # There can be multiple parameter sections
142 # The name and type should be same as charm specification
144 - name: <update, optional>
146 mandatory: <true|false>
148 # Any config or action that need to be executed when VNF comes up
149 # This is an optional section
150 initial-config-primitive:
152 # Any config to be set when VNF comes up
153 # For charm normally the VNF management IP need to be set
154 # in one of the config parameters
155 # Sepcifying the value a <rw_mgmt_ip> will cause the MANO
156 # to replace this with the management ip of VNF when it is
164 # This should be id of one of the VDUs specified for this VNF
166 port: <update, optional>
169 # Specify the connection points from VDU
170 # Can specify multiple connection points here
176 # Atleast one VDU need to be specified
180 description: ${name}-VM
182 # Image including the full path
185 # Flavour of the VM to be instantiated for the VDU
192 # Specify the external interfaces
193 # There can be multiple interfaces defined
199 vnfd-connection-point-ref: eth0
205 vnfd-connection-point-ref: eth1
207 # Mgmt vpci, match with the specification in the
208 # external interface for mgmt
209 mgmt-vpci: 0000:00:0a.0
211 # Specify EPA parameters
212 # This section is optional
214 cpu-pinning-policy: DEDICATED
215 cpu-thread-pinning-policy: PREFER
222 num-paired-threads: '1'
227 if [ $VERBOSE == true
]; then
228 echo "INFO: Created $desc_file"
232 function write_nsd_tmpl
() {
234 desc_file
="${name}_nsd.yaml"
236 cat >$desc_file <<EOF
237 # Only one NSD per descriptor package is supported
238 # Update the <update> tag with correct values
239 # Update or remove <update, optional> tags
247 # Place the logo as png in icons directory and provide the name here
248 logo: <update, optional>
250 # Specify the VNFDs that are part of this NSD
252 # The member-vnf-index needs to be unique, starting from 1
253 # vnfd-id-ref is the id of the VNFD
254 # Multiple constituent VNFDs can be specified
255 - member-vnf-index: <update>
256 vnfd-id-ref: <update>
259 # Management network for the VNFs
264 physical-network: <update>
266 vnfd-connection-point-ref:
267 # Specify all the constituent VNFs
268 # member-vnf-index-ref - entry from constituent vnf
269 # vnfd-id-ref - VNFD id
270 # vnfd-connection-point-ref - connection point name in the VNFD
271 - member-vnf-index-ref: '1'
272 vnfd-connection-point-ref: <update>
273 vnfd-id-ref: <update>
274 - member-vnf-index-ref: '2'
275 vnfd-connection-point-ref: <update>
276 vnfd-id-ref: <update>
278 # Addtional netowrk can be specified for data, etc
284 physical-network: <update>
285 vnfd-connection-point-ref:
286 - member-vnf-index-ref: <update>
287 vnfd-connection-point-ref: <update>
288 vnfd-id-ref: <update>
290 # NS level configuration primitive
291 # This section is optional
294 # List of parameters, optional
298 default-value: <update>
299 mandatory: <true|false>
301 # List of parameters grouped by name
304 - mandatory: <true|false>
309 default-value: <update>
311 mandatory: <true|false>
313 # Script based NS level configuration
314 user-defined-script: <update>
317 if [ $VERBOSE == true
]; then
318 echo "INFO: Created $desc_file"
322 function write_nsd_config_tmpl
() {
324 cfg_file
="ns_config/$name.yaml"
330 if [ $VERBOSE == true
]; then
331 echo "INFO: Created $cfg_file"
335 OPTS
=`getopt -o vhnt:d:cN --long verbose,dry-run,help,package-type:,destination-dir,create-folder,no-remove-files,debug -n $SCRIPTNAME -- "$@"`
337 if [ $?
!= 0 ] ; then
338 echo "ERROR: Failed parsing options ($?)." >&2
348 # Check if the array contains a specific value
350 # http://stackoverflow.com/questions/3685970/check-if-an-array-contains-a-value
351 function contains
() {
354 for ((i
=1;i
< $#;i
++)); do
355 if [ "${!i}" == "${value}" ]; then
364 function check_type
() {
366 if [ $
(contains
"${DESC_TYPES[@]}" $type) == "y" ]; then
369 echo "ERROR: Unknown descriptor type $type!" >&2
375 # First argument is to specify if this is a negative match or match
376 # Rest are filename expressions without extension
382 for ((i
=2;i
<= $#;i
++)); do
383 if [ $i -eq 2 ]; then
384 if [ $neg == true
]; then
390 if [ $neg == true
]; then
391 subexpr
=' -a ! -name'
397 for extn
in ${DESC_EXTN[$@]}; do
398 regex
="$regex $subexpr ${!i}.$extn"
402 if [ $VERBOSE == true
]; then
403 echo "INFO: Generate expression: $expr"
410 # First argument is to specify if this is a negative match or not
411 # Rest are filename expressions without extension
417 for ((i
=2;i
<= $#;i
++)); do
418 for extn
in "${DESC_EXTN[@]}"; do
419 if [ $first == true
]; then
420 if [ $neg == true
]; then
427 if [ $neg == true
]; then
428 subexpr
=' -a ! -name'
434 regex
="$regex $subexpr ${!i}.$extn"
443 -v |
--verbose ) VERBOSE
=true
; shift ;;
444 -h |
--help ) usage
; exit 0; shift ;;
445 -n |
--dry-run ) DRY_RUN
=true
; shift ;;
446 -t |
--package-type ) check_type
"$2"; shift; shift ;;
447 -d |
--destination-dir ) DEST_DIR
=$2; shift; shift;;
448 -c |
--create-folder ) CREATE
=true
; shift;;
449 -N |
--no-remove-files ) RM
=''; shift;;
450 --debug ) DEBUG
=true
; shift;;
456 if [ $DEBUG == true
]; then
457 echo "INFO: Debugging ON"
461 if [ $VERBOSE == true
]; then
462 echo "INFO: Descriptor type: $TYPE"
465 # Dry run is to validate existing descriptor folders
466 if [ $DRY_RUN == true
] && [ $CREATE == true
]; then
467 echo "ERROR: Option dry-run with create-folders not supported!" >&2
471 if [ $# -gt 1 ]; then
475 BASE_DIR
=$
(dirname $1)
479 if [ $VERBOSE == true
]; then
480 echo "INFO: Using base dir: $BASE_DIR"
483 if [ $VERBOSE == true
]; then
484 echo "INFO: Using package: $PKG"
487 if [ -z "$PKG" ]; then
488 echo "ERROR: Need to specify the package-dir" >&2
494 if [ $?
-ne 0 ]; then
495 echo "ERROR: Unable to change to base directory $BASE_DIR!" >&2
499 # Get full base dir path
503 if [ -z $DEST_DIR ]; then
504 DEST_DIR
=$BASE_DIR # Default to base directory
510 if [ $?
-ne 0 ]; then
511 echo "ERROR: Not able to access destination directory $DEST_DIR!" >&2
515 # Get the full destination dir path
519 dir
=${BASE_DIR}/${PKG}
521 function add_chksum
() {
522 if [ $VERBOSE == true
]; then
523 echo "INFO: Add file $1 to $CHKSUM"
529 if [ $CREATE == false
]; then
530 if [ ! -d $dir ]; then
531 echo "INFO: Package folder $dir not found!" >&2
536 if [ $?
-ne 0 ]; then
538 echo "ERROR: changing directory to $dir ($rc)" >&2
542 # Remove checksum file, if present
545 # Check if the descriptor file is present
546 if [ -z $TYPE ]; then
547 # Desc type not specified, look for the desc file and guess the type
548 # Required for backward compatibility
549 for ty
in ${DESC_TYPES[@]}; do
550 re
=$
(get_expr false
"$ty" "*_$ty" "*_${ty}_*")
551 desc
=$
(find * -maxdepth 0 -type f
$re 2>/dev
/null
)
553 if [ -z $desc ] ||
[ ${#desc[@]} -eq 0 ]; then
554 # Check the vnfd|nsd folder
555 if [ ! -d $ty ]; then
558 re
=$
(get_expr false
"*")
559 desc
=$
(find $ty/* -maxdepth 0 -type f
$re 2>/dev
/null
)
560 if [ -z $desc ] ||
[ ${#desc[@]} -eq 0 ]; then
562 elif [ ${#desc[@]} -gt 1 ]; then
563 echo "ERROR: Found multiple descriptor files: ${desc[@]}" >&2
566 # Descriptor sub directory
571 if [ $TYPE == 'nsd' ]; then
572 folders
=("${NSD_FOLDERS[@]}")
574 folders
=("${VNFD_FOLDERS[@]}")
577 if [ $VERBOSE == true
]; then
578 echo "INFO: Determined descriptor is of type $TYPE"
583 if [ -z $TYPE ]; then
584 echo "ERROR: Unable to determine the descriptor type!" >&2
588 if [ $TYPE == 'nsd' ]; then
589 folders
=("${NSD_FOLDERS[@]}")
591 folders
=("${VNFD_FOLDERS[@]}")
594 # Check for descriptor of type provided on command line
595 re
=$
(get_expr false
"$TYPE" "*_${TYPE}" "*_${TYPE}_*")
596 desc
=$
(find * -maxdepth 0 -type f
$re 2>/dev
/null
)
598 if [ -z $desc ] ||
[ ${#desc[@]} -eq 0 ]; then
599 # Check if it is under vnfd/nsd subdirectory
600 # Backward compatibility support
601 re
=$
(get_expr false
"*")
602 desc
=$
(find $TYPE/* -maxdepth 0 -type f
$re 2>/dev
/null
)
603 if [ -z $desc ] ||
[ ${#desc[@]} -eq 0 ]; then
604 echo "ERROR: Did not find descriptor file of type $TYPE" \
612 if [ ${#desc[@]} -gt 1 ]; then
613 echo "ERROR: Found multiple files of type $TYPE in $dir: $desc" >&2
617 descriptor
=${desc[0]}
619 # Check if there are files not supported
620 files
=$
(find * -maxdepth 0 -type f
! -name $descriptor 2>/dev
/null
)
622 for f
in ${files[@]}; do
623 if [ $
(contains
"${ALLOWED_FILES[@]}" $f) == "n" ]; then
624 echo "WARN: Unsupported file $f found"
628 if [ $VERBOSE == true
]; then
629 echo "INFO: Found descriptor package: ${desc_sub_dir} ${descriptor}"
632 if [ $DRY_RUN == false
]; then
633 add_chksum
${descriptor}
636 # Check the folders are supported ones
637 dirs=$
( find * -maxdepth 0 -type d
)
639 for d
in ${dirs[@]}; do
640 if [ $
(contains
"${folders[@]}" $d) == "y" ]; then
641 if [ $DRY_RUN == false
]; then
642 find $d/* -type f
2>/dev
/null|
647 elif [ -z $desc_sub_dir ] ||
[ $d != $desc_sub_dir ]; then
648 echo "WARN: $d is not part of standard folders " \
649 "for descriptor type $TYPE in $PKG"
653 if [ $VERBOSE == true
]; then
654 echo "INFO: Creating archive for $PKG"
658 if [ $DRY_RUN == false
]; then
659 tar zcvf
"$DEST_DIR/$PKG.tar.gz" "${PKG}" ${RM}
660 if [ $?
-ne 0 ]; then
662 echo "ERROR: creating archive for $PKG ($rc)" >&2
667 # Create the folders for the descriptor
668 if [ $VERBOSE == true
]; then
669 echo "INFO: Creating folders for $PKG in $dir"
672 # Create, default to VNFD if no type is defined
673 if [ -z $TYPE ]; then
675 echo "WARNING: Defaulting to descriptor type $TYPE"
678 mkdir
-p $dir && cd $dir
679 if [ $?
-ne 0 ]; then
681 echo "ERROR: creating directory $dir ($rc)" >&2
685 if [ $TYPE == 'nsd' ]; then
686 folders
=("${NSD_FOLDERS[@]}")
688 folders
=("${VNFD_FOLDERS[@]}")
691 for d
in ${folders[@]}; do
693 if [ $?
-ne 0 ]; then
695 echo "ERROR: creating directory $dir/$d ($rc)" >&2
698 if [ $VERBOSE == true
]; then
699 echo "Created folder $d in $dir"
703 if [ $VERBOSE == true
]; then
704 echo "INFO: Created folders for in $dir"
707 # Write a descriptor template file
708 if [ $TYPE == 'vnfd' ]; then
712 # write_nsd_config_tmpl $dir