Files
Joachim WibergandTobias Waldekranz d70abc5f21 board/common: let dagger script set LOG_PID with parent PID
This adds [PPID] to the syslog lines to the dagger script.  After all,
the dagger script is a proxy for confd, so when reading the logs it
seems natural to see the PID of confd rather than a script that will
die soon anyway.

Signed-off-by: Joachim Wiberg <troglobit@gmail.com>
2024-01-09 21:24:41 +01:00

182 lines
3.4 KiB
Bash
Executable File

#!/bin/sh
set -e
inform()
{
local level="$1"
shift
logger -p "daemon.$level" -I $PPID -t dagger -c $LOGGER_STDOUT "$@"
}
abort()
{
inform err "Aborting: $*"
exit 1
}
generate_order()
{
[ -f "$1/bottom-up-order" ] && [ -f "$1/top-down-order" ] && return
# The bottom-up order corresponds to a DFS through the DAG, with
# duplicates removed
find -L "$1/dag" -depth -mindepth 1 -exec basename {} \; \
| awk '!seen[$0]++' \
>"$1/bottom-up-order"
# The reverse is a valid top-down order
sed '1!G;h;$!d' "$1/bottom-up-order" >"$1/top-down-order"
}
action_exec()
{
local actdir="$2/action/$1"
local orderfile="$actdir/order"
local code=0
generate_order "$2"
if [ ! -r "$orderfile" ]; then
orderfile="$2/bottom-up-order"
inform warn "No order defined for $actdir, falling back to bottom-up"
fi
local order=$(cat "$orderfile")
[ -d "$actdir/@pre" ] && order="@pre $order"
[ -d "$actdir/@post" ] && order="$order @post"
for node in $order; do
for work in $(find "$actdir/$node" -type f -executable 2>/dev/null | sort); do
$work >>"$work.log" 2>&1 || code=$?
echo "[exit:$code]" >>"$work.log"
[ $code -eq 0 ] || abort "$work failed with exitcode $code"
done
done
}
do_exec()
{
local action="$1"
local current=
current=$([ -f "$basedir/current" ] && cat "$basedir/current")
[ "$current" ] && [ -d "$basedir/$current" ] \
|| abort "Current generation does not exist"
action_exec "$1" "$basedir/$current"
}
do_abandon()
{
local next=
next=$([ -f "$basedir/next" ] && cat "$basedir/next" || true)
[ "$next" ] && [ -d "$basedir/$next" ] \
|| abort "Next generation does not exist"
mv "$basedir/$next" "$basedir/$next-ABANDONED-$(date +%F-%T)"
rm "$basedir/next"
inform info "Abandoned generation $next"
}
do_evolve()
{
local current=
local next=
current=$([ -f "$basedir/current" ] && cat "$basedir/current" || true)
[ ! "$current" ] || [ -d "$basedir/$current" ] \
|| abort "Current generation does not exist"
next=$([ -f "$basedir/next" ] && cat "$basedir/next" || true)
[ "$next" ] && [ -d "$basedir/$next" ] \
|| abort "Next generation does not exist"
[ "$current" ] && action_exec exit "$basedir/$current"
action_exec init "$basedir/$next"
mv "$basedir/next" "$basedir/current"
inform info "Evolved to generation $next"
}
usage()
{
cat <<EOF
usage: dagger [-d] [-C <root>] <command> [<args>]
Directed Acyclic Graph Generational Execution Runner
Global options:
-d
In addition to the system log, also log messages to stderr.
-C <root>
Instead of the current working directory, use <root> as the dagger
root directory.
Commands:
abandon
Abandon a prepared, but not yet applied, next generation.
evolve
Run the exit action of the current generation, followed by the
init action of the next generation.
exec <action>
Run the specified action of the current generation.
help
Show this message.
EOF
}
basedir=$(pwd)
# Global options
while getopts "dC:" opt; do
case $opt in
d)
LOGGER_STDOUT=-s
;;
C)
basedir=$OPTARG
;;
*)
usage && exit 1
esac
done
shift $((OPTIND - 1))
if [ $# -lt 1 ]; then
usage && exit 1
fi
cmd=$1
shift
case $cmd in
"help")
usage && exit 0
;;
"abandon")
do_abandon
;;
"evolve")
do_evolve
;;
"exec")
do_exec "$@"
;;
*)
usage && exit 1
esac