diff options
Diffstat (limited to 'scripts')
-rwxr-xr-x | scripts/contrib/python/generate-manifest-3.5.py | 2 | ||||
-rw-r--r-- | scripts/lib/checklayer/__init__.py | 4 | ||||
-rw-r--r-- | scripts/lib/devtool/sdk.py | 3 | ||||
-rw-r--r-- | scripts/lib/recipetool/create.py | 8 | ||||
-rw-r--r-- | scripts/lib/wic/filemap.py | 10 | ||||
-rw-r--r-- | scripts/lib/wic/partition.py | 2 | ||||
-rw-r--r-- | scripts/lib/wic/plugins/source/rawcopy.py | 22 | ||||
-rw-r--r-- | scripts/multilib_header_wrapper.h | 4 | ||||
-rwxr-xr-x | scripts/oe-build-perf-report | 11 | ||||
-rwxr-xr-x | scripts/runqemu | 5 | ||||
-rwxr-xr-x | scripts/test-dependencies.sh | 286 |
11 files changed, 54 insertions, 303 deletions
diff --git a/scripts/contrib/python/generate-manifest-3.5.py b/scripts/contrib/python/generate-manifest-3.5.py index 6352f8f120..750d4fc754 100755 --- a/scripts/contrib/python/generate-manifest-3.5.py +++ b/scripts/contrib/python/generate-manifest-3.5.py @@ -371,7 +371,7 @@ if __name__ == "__main__": "lib-dynload/readline.*.so rlcompleter.*" ) m.addPackage( "${PN}-reprlib", "Python alternate repr() implementation", "${PN}-core", - "reprlib.py" ) + "reprlib.*" ) m.addPackage( "${PN}-resource", "Python resource control interface", "${PN}-core", "lib-dynload/resource.*.so" ) diff --git a/scripts/lib/checklayer/__init__.py b/scripts/lib/checklayer/__init__.py index 63952616ba..288c457822 100644 --- a/scripts/lib/checklayer/__init__.py +++ b/scripts/lib/checklayer/__init__.py @@ -42,8 +42,8 @@ def _get_layer_collections(layer_path, lconf=None, data=None): ldata.setVar('LAYERDIR', layer_path) try: ldata = bb.parse.handle(lconf, ldata, include=True) - except BaseException as exc: - raise LayerError(exc) + except: + raise RuntimeError("Parsing of layer.conf from layer: %s failed" % layer_path) ldata.expandVarref('LAYERDIR') collections = (ldata.getVar('BBFILE_COLLECTIONS') or '').split() diff --git a/scripts/lib/devtool/sdk.py b/scripts/lib/devtool/sdk.py index f46577c2ab..4616753797 100644 --- a/scripts/lib/devtool/sdk.py +++ b/scripts/lib/devtool/sdk.py @@ -145,6 +145,9 @@ def sdk_update(args, config, basepath, workspace): # Fetch manifest from server tmpmanifest = os.path.join(tmpsdk_dir, 'conf', 'sdk-conf-manifest') ret = subprocess.call("wget -q -O %s %s/conf/sdk-conf-manifest" % (tmpmanifest, updateserver), shell=True) + if ret != 0: + logger.error("Cannot dowload files from %s" % updateserver) + return ret changedfiles = check_manifest(tmpmanifest, basepath) if not changedfiles: logger.info("Already up-to-date") diff --git a/scripts/lib/recipetool/create.py b/scripts/lib/recipetool/create.py index 055bdef436..5bf939efcb 100644 --- a/scripts/lib/recipetool/create.py +++ b/scripts/lib/recipetool/create.py @@ -477,7 +477,6 @@ def create_recipe(args): if tag: # Keep a copy of tag and append nobranch=1 then remove tag from URL. # Bitbake fetcher unable to fetch when {AUTOREV} and tag is set at the same time. - # We will re-introduce tag argument after bitbake fetcher process is complete. storeTagName = params['tag'] params['nobranch'] = '1' del params['tag'] @@ -549,13 +548,11 @@ def create_recipe(args): # Since we might have a value in srcbranch, we need to # recontruct the srcuri to include 'branch' in params. + scheme, network, path, user, passwd, params = bb.fetch2.decodeurl(srcuri) if srcbranch: - scheme, network, path, user, passwd, params = bb.fetch2.decodeurl(srcuri) params['branch'] = srcbranch - srcuri = bb.fetch2.encodeurl((scheme, network, path, user, passwd, params)) if storeTagName and scheme in ['git', 'gitsm']: - # Re-introduced tag variable from storeTagName # Check srcrev using tag and check validity of the tag cmd = ('git rev-parse --verify %s' % (storeTagName)) try: @@ -565,6 +562,9 @@ def create_recipe(args): logger.error(str(err)) logger.error("Possibly wrong tag name is provided") sys.exit(1) + # Drop tag from srcuri as it will have conflicts with SRCREV during recipe parse. + del params['tag'] + srcuri = bb.fetch2.encodeurl((scheme, network, path, user, passwd, params)) if os.path.exists(os.path.join(srctree, '.gitmodules')) and srcuri.startswith('git://'): srcuri = 'gitsm://' + srcuri[6:] diff --git a/scripts/lib/wic/filemap.py b/scripts/lib/wic/filemap.py index 77e32b9add..a72fa09ef5 100644 --- a/scripts/lib/wic/filemap.py +++ b/scripts/lib/wic/filemap.py @@ -37,7 +37,15 @@ def get_block_size(file_obj): # Get the block size of the host file-system for the image file by calling # the FIGETBSZ ioctl (number 2). binary_data = fcntl.ioctl(file_obj, 2, struct.pack('I', 0)) - return struct.unpack('I', binary_data)[0] + bsize = struct.unpack('I', binary_data)[0] + if not bsize: + import os + stat = os.fstat(file_obj.fileno()) + if hasattr(stat, 'st_blksize'): + bsize = stat.st_blksize + else: + raise IOError("Unable to determine block size") + return bsize class ErrorNotSupp(Exception): """ diff --git a/scripts/lib/wic/partition.py b/scripts/lib/wic/partition.py index 66e61ba70c..84fe85d62b 100644 --- a/scripts/lib/wic/partition.py +++ b/scripts/lib/wic/partition.py @@ -206,7 +206,7 @@ class Partition(): """ p_prefix = os.environ.get("PSEUDO_PREFIX", "%s/usr" % native_sysroot) p_localstatedir = os.environ.get("PSEUDO_LOCALSTATEDIR", - "%s/../pseudo" % rootfs_dir) + "%s/../pseudo" % get_bitbake_var("IMAGE_ROOTFS")) p_passwd = os.environ.get("PSEUDO_PASSWD", rootfs_dir) p_nosymlinkexp = os.environ.get("PSEUDO_NOSYMLINKEXP", "1") pseudo = "export PSEUDO_PREFIX=%s;" % p_prefix diff --git a/scripts/lib/wic/plugins/source/rawcopy.py b/scripts/lib/wic/plugins/source/rawcopy.py index 424ed26ed6..e86398ac8f 100644 --- a/scripts/lib/wic/plugins/source/rawcopy.py +++ b/scripts/lib/wic/plugins/source/rawcopy.py @@ -32,6 +32,25 @@ class RawCopyPlugin(SourcePlugin): name = 'rawcopy' + @staticmethod + def do_image_label(fstype, dst, label): + if fstype.startswith('ext'): + cmd = 'tune2fs -L %s %s' % (label, dst) + elif fstype in ('msdos', 'vfat'): + cmd = 'dosfslabel %s %s' % (dst, label) + elif fstype == 'btrfs': + cmd = 'btrfs filesystem label %s %s' % (dst, label) + elif fstype == 'swap': + cmd = 'mkswap -L %s %s' % (label, dst) + elif fstype == 'squashfs': + raise WicError("It's not possible to update a squashfs " + "filesystem label '%s'" % (label)) + else: + raise WicError("Cannot update filesystem label: " + "Unknown fstype: '%s'" % (fstype)) + + exec_cmd(cmd) + @classmethod def do_prepare_partition(cls, part, source_params, cr, cr_workdir, oe_builddir, bootimg_dir, kernel_dir, @@ -66,4 +85,7 @@ class RawCopyPlugin(SourcePlugin): if filesize > part.size: part.size = filesize + if part.label: + RawCopyPlugin.do_image_label(part.fstype, dst, part.label) + part.source_file = dst diff --git a/scripts/multilib_header_wrapper.h b/scripts/multilib_header_wrapper.h index f516673b63..9660225fdd 100644 --- a/scripts/multilib_header_wrapper.h +++ b/scripts/multilib_header_wrapper.h @@ -22,7 +22,9 @@ */ -#if defined (__arm__) +#if defined (__bpf__) +#define __MHWORDSIZE 64 +#elif defined (__arm__) #define __MHWORDSIZE 32 #elif defined (__aarch64__) && defined ( __LP64__) #define __MHWORDSIZE 64 diff --git a/scripts/oe-build-perf-report b/scripts/oe-build-perf-report index ac88f0fce5..dc999c45c1 100755 --- a/scripts/oe-build-perf-report +++ b/scripts/oe-build-perf-report @@ -639,10 +639,6 @@ def main(argv=None): data.append(AggregateTestData(aggregate_metadata(raw_m), aggregate_data(raw_d))) - # Re-map list indexes to the new table starting from index 0 - index_r = index_r - index_0 - index_l = index_l - index_0 - # Read buildstats only when needed buildstats = None if args.dump_buildstats or args.html: @@ -653,10 +649,11 @@ def main(argv=None): # Print report if not args.html: - print_diff_report(data[index_l].metadata, data[index_l].results, - data[index_r].metadata, data[index_r].results) + print_diff_report(data[0].metadata, data[0].results, + data[1].metadata, data[1].results) else: - print_html_report(data, index_l, buildstats) + # Re-map 'left' list index to the data table where index_0 maps to 0 + print_html_report(data, index_l - index_0, buildstats) return 0 diff --git a/scripts/runqemu b/scripts/runqemu index 0b6daf2cf2..0ed1eec2d3 100755 --- a/scripts/runqemu +++ b/scripts/runqemu @@ -508,6 +508,11 @@ class BaseConfig(object): if os.access(dev_kvm, os.W_OK|os.R_OK): self.qemu_opt_script += ' -enable-kvm' + if self.get('MACHINE') == "qemux86": + # Workaround for broken APIC window on pre 4.15 host kernels which causes boot hangs + # See YOCTO #12301 + # On 64 bit we use x2apic + self.kernel_cmdline_script += " clocksource=kvm-clock hpet=disable noapic nolapic" else: logger.error("You have no read or write permission on /dev/kvm.") logger.error("Please change the ownership of this file as described at:") diff --git a/scripts/test-dependencies.sh b/scripts/test-dependencies.sh deleted file mode 100755 index 0b94de8608..0000000000 --- a/scripts/test-dependencies.sh +++ /dev/null @@ -1,286 +0,0 @@ -#!/bin/bash - -# Author: Martin Jansa <martin.jansa@gmail.com> -# -# Copyright (c) 2013 Martin Jansa <Martin.Jansa@gmail.com> - -# Used to detect missing dependencies or automagically -# enabled dependencies which aren't explicitly enabled -# or disabled. Using bash to have PIPESTATUS variable. - -# It does 3 builds of <target> -# 1st to populate sstate-cache directory and sysroot -# 2nd to rebuild each recipe with every possible -# dependency found in sysroot (which stays populated -# from 1st build -# 3rd to rebuild each recipe only with dependencies defined -# in DEPENDS -# 4th (optional) repeat build like 3rd to make sure that -# minimal versions of dependencies defined in DEPENDS -# is also enough - -# Global vars -tmpdir= -targets= -recipes= -buildhistory= -buildtype= -default_targets="world" -default_buildhistory="buildhistory" -default_buildtype="1 2 3 c" - -usage () { - cat << EOF -Welcome to utility to detect missing or autoenabled dependencies. -WARNING: this utility will completely remove your tmpdir (make sure - you don't have important buildhistory or persistent dir there). -$0 <OPTION> - -Options: - -h, --help - Display this help and exit. - - --tmpdir=<tmpdir> - Specify tmpdir, will use the environment variable TMPDIR if it is not specified. - Something like /OE/oe-core/tmp-eglibc (no / at the end). - - --targets=<targets> - List of targets separated by space, will use the environment variable TARGETS if it is not specified. - It will run "bitbake <targets>" to populate sysroots. - Default value is "world". - - --recipes=<recipes> - File with list of recipes we want to rebuild with minimal and maximal sysroot. - Will use the environment variable RECIPES if it is not specified. - Default value will use all packages ever recorded in buildhistory directory. - - --buildhistory=<buildhistory> - Path to buildhistory directory, it needs to be enabled in your config, - because it's used to detect different dependencies and to create list - of recipes to rebuild when it's not specified. - Will use the environment variable BUILDHISTORY if it is not specified. - Default value is "buildhistory" - - --buildtype=<buildtype> - There are 4 types of build: - 1: build to populate sstate-cache directory and sysroot - 2: build to rebuild each recipe with every possible dep - 3: build to rebuild each recipe with minimal dependencies - 4: build to rebuild each recipe again with minimal dependencies - c: compare buildhistory directories from build 2 and 3 - Will use the environment variable BUILDTYPE if it is not specified. - Default value is "1 2 3 c", order is important, type 4 is optional. -EOF -} - -# Print error information and exit. -echo_error () { - echo "ERROR: $1" >&2 - exit 1 -} - -while [ -n "$1" ]; do - case $1 in - --tmpdir=*) - tmpdir=`echo $1 | sed -e 's#^--tmpdir=##' | xargs readlink -e` - [ -d "$tmpdir" ] || echo_error "Invalid argument to --tmpdir" - shift - ;; - --targets=*) - targets=`echo $1 | sed -e 's#^--targets="*\([^"]*\)"*#\1#'` - shift - ;; - --recipes=*) - recipes=`echo $1 | sed -e 's#^--recipes="*\([^"]*\)"*#\1#'` - shift - ;; - --buildhistory=*) - buildhistory=`echo $1 | sed -e 's#^--buildhistory="*\([^"]*\)"*#\1#'` - shift - ;; - --buildtype=*) - buildtype=`echo $1 | sed -e 's#^--buildtype="*\([^"]*\)"*#\1#'` - shift - ;; - --help|-h) - usage - exit 0 - ;; - *) - echo "Invalid arguments $*" - echo_error "Try '$0 -h' for more information." - ;; - esac -done - -# tmpdir directory, use environment variable TMPDIR -# if it was not specified, otherwise, error. -[ -n "$tmpdir" ] || tmpdir=$TMPDIR -[ -n "$tmpdir" ] || echo_error "No tmpdir found!" -[ -d "$tmpdir" ] || echo_error "Invalid tmpdir \"$tmpdir\"" -[ -n "$targets" ] || targets=$TARGETS -[ -n "$targets" ] || targets=$default_targets -[ -n "$recipes" ] || recipes=$RECIPES -[ -n "$recipes" -a ! -f "$recipes" ] && echo_error "Invalid file with list of recipes to rebuild" -[ -n "$recipes" ] || echo "All packages ever recorded in buildhistory directory will be rebuilt" -[ -n "$buildhistory" ] || buildhistory=$BUILDHISTORY -[ -n "$buildhistory" ] || buildhistory=$default_buildhistory -[ -d "$buildhistory" ] || echo_error "Invalid buildhistory directory \"$buildhistory\"" -[ -n "$buildtype" ] || buildtype=$BUILDTYPE -[ -n "$buildtype" ] || buildtype=$default_buildtype -echo "$buildtype" | grep -v '^[1234c ]*$' && echo_error "Invalid buildtype \"$buildtype\", only some combination of 1, 2, 3, 4, c separated by space is allowed" - -OUTPUT_BASE=test-dependencies/`date "+%s"` -declare -i RESULT=0 - -build_all() { - echo "===== 1st build to populate sstate-cache directory and sysroot =====" - OUTPUT1=${OUTPUT_BASE}/${TYPE}_all - mkdir -p ${OUTPUT1} - echo "Logs will be stored in ${OUTPUT1} directory" - bitbake -k $targets 2>&1 | tee -a ${OUTPUT1}/complete.log - RESULT+=${PIPESTATUS[0]} - grep "ERROR: Task.*failed" ${OUTPUT1}/complete.log > ${OUTPUT1}/failed-tasks.log - cat ${OUTPUT1}/failed-tasks.log | sed 's@.*/@@g; s@_.*@@g; s@\.bb, .*@@g; s@\.bb:.*@@g' | sort -u > ${OUTPUT1}/failed-recipes.log -} - -build_every_recipe() { - if [ "${TYPE}" = "2" ] ; then - echo "===== 2nd build to rebuild each recipe with every possible dep =====" - OUTPUT_MAX=${OUTPUT_BASE}/${TYPE}_max - OUTPUTB=${OUTPUT_MAX} - else - echo "===== 3rd or 4th build to rebuild each recipe with minimal dependencies =====" - OUTPUT_MIN=${OUTPUT_BASE}/${TYPE}_min - OUTPUTB=${OUTPUT_MIN} - fi - - mkdir -p ${OUTPUTB} ${OUTPUTB}/failed ${OUTPUTB}/ok - echo "Logs will be stored in ${OUTPUTB} directory" - if [ -z "$recipes" ]; then - ls -d $buildhistory/packages/*/* | xargs -n 1 basename | sort -u > ${OUTPUTB}/recipe.list - recipes=${OUTPUTB}/recipe.list - fi - if [ "${TYPE}" != "2" ] ; then - echo "!!!Removing tmpdir \"$tmpdir\"!!!" - rm -rf $tmpdir/deploy $tmpdir/pkgdata $tmpdir/sstate-control $tmpdir/stamps $tmpdir/sysroots $tmpdir/work $tmpdir/work-shared 2>/dev/null - fi - i=1 - count=`cat $recipes ${OUTPUT1}/failed-recipes.log | sort -u | wc -l` - for recipe in `cat $recipes ${OUTPUT1}/failed-recipes.log | sort -u`; do - echo "Building recipe: ${recipe} ($i/$count)" - declare -i RECIPE_RESULT=0 - bitbake -c cleansstate ${recipe} > ${OUTPUTB}/${recipe}.log 2>&1; - RECIPE_RESULT+=$? - bitbake ${recipe} >> ${OUTPUTB}/${recipe}.log 2>&1; - RECIPE_RESULT+=$? - if [ "${RECIPE_RESULT}" != "0" ] ; then - RESULT+=${RECIPE_RESULT} - mv ${OUTPUTB}/${recipe}.log ${OUTPUTB}/failed/ - grep "ERROR: Task.*failed" ${OUTPUTB}/failed/${recipe}.log | tee -a ${OUTPUTB}/failed-tasks.log - grep "ERROR: Task.*failed" ${OUTPUTB}/failed/${recipe}.log | sed 's@.*/@@g; s@_.*@@g; s@\.bb, .*@@g; s@\.bb:.*@@g' >> ${OUTPUTB}/failed-recipes.log - # and append also ${recipe} in case the failed task was from some dependency - echo ${recipe} >> ${OUTPUTB}/failed-recipes.log - else - mv ${OUTPUTB}/${recipe}.log ${OUTPUTB}/ok/ - fi - if [ "${TYPE}" != "2" ] ; then - rm -rf $tmpdir/deploy $tmpdir/pkgdata $tmpdir/sstate-control $tmpdir/stamps $tmpdir/sysroots $tmpdir/work $tmpdir/work-shared 2>/dev/null - fi - i=`expr $i + 1` - done - echo "Copying buildhistory/packages to ${OUTPUTB}" - cp -ra $buildhistory/packages ${OUTPUTB} - # This will be usefull to see which library is pulling new dependency - echo "Copying do_package logs to ${OUTPUTB}/do_package/" - mkdir ${OUTPUTB}/do_package - find $tmpdir/work/ -name log.do_package 2>/dev/null| while read f; do - # pn is 3 levels back, but we don't know if there is just one log per pn (only one arch and version) - # dest=`echo $f | sed 's#^.*/\([^/]*\)/\([^/]*\)/\([^/]*\)/log.do_package#\1#g'` - dest=`echo $f | sed "s#$tmpdir/work/##g; s#/#_#g"` - cp $f ${OUTPUTB}/do_package/$dest - done -} - -compare_deps() { - # you can run just compare task with command like this - # OUTPUT_BASE=test-dependencies/1373140172 \ - # OUTPUT_MAX=${OUTPUT_BASE}/2_max \ - # OUTPUT_MIN=${OUTPUT_BASE}/3_min \ - # openembedded-core/scripts/test-dependencies.sh --tmpdir=tmp-eglibc --targets=glib-2.0 --recipes=recipe_list --buildtype=c - echo "===== Compare dependencies recorded in \"${OUTPUT_MAX}\" and \"${OUTPUT_MIN}\" =====" - [ -n "${OUTPUTC}" ] || OUTPUTC=${OUTPUT_BASE}/comp - mkdir -p ${OUTPUTC} - OUTPUT_FILE=${OUTPUTC}/dependency-changes - echo "Differences will be stored in ${OUTPUT_FILE}, dot is shown for every 100 of checked packages" - echo > ${OUTPUT_FILE} - - [ -d ${OUTPUT_MAX} ] || echo_error "Directory with output from build 2 \"${OUTPUT_MAX}\" does not exist" - [ -d ${OUTPUT_MIN} ] || echo_error "Directory with output from build 3 \"${OUTPUT_MIN}\" does not exist" - [ -d ${OUTPUT_MAX}/packages/ ] || echo_error "Directory with packages from build 2 \"${OUTPUT_MAX}/packages/\" does not exist" - [ -d ${OUTPUT_MIN}/packages/ ] || echo_error "Directory with packages from build 3 \"${OUTPUT_MIN}/packages/\" does not exist" - i=0 - find ${OUTPUT_MAX}/packages/ -name latest | sed "s#${OUTPUT_MAX}/##g" | while read pkg; do - max_pkg=${OUTPUT_MAX}/${pkg} - min_pkg=${OUTPUT_MIN}/${pkg} - # pkg=packages/armv5te-oe-linux-gnueabi/libungif/libungif/latest - recipe=`echo "${pkg}" | sed 's#packages/[^/]*/\([^/]*\)/\([^/]*\)/latest#\1#g'` - package=`echo "${pkg}" | sed 's#packages/[^/]*/\([^/]*\)/\([^/]*\)/latest#\2#g'` - if [ ! -f "${min_pkg}" ] ; then - echo "ERROR: ${recipe}: ${package} package isn't created when building with minimal dependencies?" | tee -a ${OUTPUT_FILE} - echo ${recipe} >> ${OUTPUTC}/failed-recipes.log - continue - fi - # strip version information in parenthesis - max_deps=`grep "^RDEPENDS = " ${max_pkg} | sed 's/^RDEPENDS = / /g; s/$/ /g; s/([^(]*)//g'` - min_deps=`grep "^RDEPENDS = " ${min_pkg} | sed 's/^RDEPENDS = / /g; s/$/ /g; s/([^(]*)//g'` - if [ "$i" = 100 ] ; then - echo -n "." # cheap progressbar - i=0 - fi - if [ "${max_deps}" = "${min_deps}" ] ; then - # it's annoying long, but at least it's showing some progress, warnings are grepped at the end - echo "NOTE: ${recipe}: ${package} rdepends weren't changed" >> ${OUTPUT_FILE} - else - missing_deps= - for dep in ${max_deps}; do - if ! echo "${min_deps}" | grep -q " ${dep} " ; then - missing_deps="${missing_deps} ${dep}" - echo # to get rid of dots on last line - echo "WARN: ${recipe}: ${package} rdepends on ${dep}, but it isn't a build dependency?" | tee -a ${OUTPUT_FILE} - fi - done - if [ -n "${missing_deps}" ] ; then - echo ${recipe} >> ${OUTPUTC}/failed-recipes.log - fi - fi - i=`expr $i + 1` - done - echo # to get rid of dots on last line - echo "Found differences: " - grep "^WARN: " ${OUTPUT_FILE} | tee ${OUTPUT_FILE}.warn.log - echo "Found errors: " - grep "^ERROR: " ${OUTPUT_FILE} | tee ${OUTPUT_FILE}.error.log - RESULT+=`cat ${OUTPUT_FILE}.warn.log | wc -l` - RESULT+=`cat ${OUTPUT_FILE}.error.log | wc -l` -} - -for TYPE in $buildtype; do - case ${TYPE} in - 1) build_all;; - 2) build_every_recipe;; - 3) build_every_recipe;; - 4) build_every_recipe;; - c) compare_deps;; - *) echo_error "Invalid buildtype \"$TYPE\"" - esac -done - -cat ${OUTPUT_BASE}/*/failed-recipes.log | sort -u >> ${OUTPUT_BASE}/failed-recipes.log - -if [ "${RESULT}" != "0" ] ; then - echo "ERROR: ${RESULT} issues were found in these recipes: `cat ${OUTPUT_BASE}/failed-recipes.log | xargs`" -fi - -echo "INFO: Output written in: ${OUTPUT_BASE}" -exit ${RESULT} |