diskimage-builder/elements/dib-run-parts/bin/dib-run-parts
James Slagle 79f31d0476 dib-run-parts should dereference symlinks
dib-run-parts should dereference symlinks, and if they point to an
executable file, execute that file as a script. This can be accomplished
by using the xtype predicate in the find command instead of the type
predicate.

This change is needed so that we can dynamically symlink hook scripts
into hook directories such as install.d at runtime to support different
install types.

Change-Id: I933e7f4b4dcf16956841d8c14aa63b0f9a18fc5d
2014-01-15 14:57:08 -05:00

107 lines
3 KiB
Bash
Executable file

#!/bin/bash
# Inspired by Debian and RedHat run-parts but portable and specific to di-b.
#
# Copyright 2012 Hewlett-Packard Development Company, L.P.
# 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.
allowed_regex=${RUN_PARTS_REGEX:-"^[0-9A-Za-z_-]+$"}
show_list=
set -ue
name=$(basename $0)
usage() {
echo "Usage: $name [OPTION] scripts_directory"
echo "Option:"
echo " --list print names of all valid files"
echo
echo "Examples:"
echo " dib-run-parts --list /opt/stack/os-config-refresh/configure.d/"
echo " dib-run-parts /opt/stack/os-config-refresh/configure.d/"
exit 1
} >&2
output () {
echo $name $(date) $* >&2
}
if [ $# -lt 1 ] ; then
usage
fi
if [ "$1" == "--list" ] ; then
show_list="1"
shift
fi
target_dir="${1:-}"
if ! [ -d "$target_dir" ] ; then
output "Scripts directory [$target_dir] must exist and be a directory"
usage
fi
# We specifically only want to sort *by the numbers*.
# Lexical sorting is not guaranteed, and identical numbers may be
# parallelized later
# Note: -maxdepth 1 ensures only files in the target directory (but not
# subdirectories) are run, which is the way run-parts behaves.
targets=$(find $target_dir -maxdepth 1 -xtype f -executable -printf '%f\n' | grep -E "$allowed_regex" | LANG=C sort -n)
if [ "$show_list" == "1" ] ; then
for target in $targets ; do
echo "${target_dir}/${target}"
done
exit 0
fi
PROFILE_DIR=$(mktemp -d /tmp/profiledir.XXXXXX)
if [ -d /tmp/in_target.d/environment.d ] ; then
for env_file in /tmp/in_target.d/environment.d/* ; do
source $env_file
done
fi
for target in $targets ; do
output "Running $target_dir/$target"
target_tag=${target//\//_}
date +%s.%N > $PROFILE_DIR/start_$target_tag
$target_dir/$target
target_tag=${target//\//_}
date +%s.%N > $PROFILE_DIR/stop_$target_tag
output "$target completed"
done
echo "----------------------- PROFILING -----------------------"
echo ""
echo "Target: $(basename $target_dir)"
echo ""
printf "%-40s %9s\n" Script Seconds
printf "%-40s %9s\n" --------------------------------------- ----------
echo ""
pushd $PROFILE_DIR > /dev/null
for target in $(find . -name 'start_*' -printf '%f\n') ; do
stop_file=stop_${target##start_}
start_seconds=$(cat $target)
stop_seconds=$(cat $stop_file)
duration=$(python -c "print $stop_seconds - $start_seconds")
LC_NUMERIC=C printf "%-40s %10.3f\n" ${target##start_} $duration
done
popd > /dev/null
rm -rf $PROFILE_DIR
echo ""
echo "--------------------- END PROFILING ---------------------"