79f31d0476
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
108 lines
3.0 KiB
Bash
Executable File
108 lines
3.0 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 ---------------------"
|