mirror of
https://github.com/kata-containers/kata-containers.git
synced 2025-04-27 11:31:05 +00:00
> Tips depend on target shell and yours is unknown. Add a shebang. Add ``` #!/usr/bin/env bash ``` Signed-off-by: stevenhorsman <steven@uk.ibm.com>
223 lines
4.3 KiB
Bash
223 lines
4.3 KiB
Bash
#!/usr/bin/env bash
|
|
#
|
|
# Copyright (c) 2022-2024 Intel Corporation
|
|
#
|
|
# SPDX-License-Identifier: Apache-2.0
|
|
#
|
|
# Description: Error handling functions.
|
|
|
|
# Write specified message to stderr.
|
|
stderr()
|
|
{
|
|
local msg="$*"
|
|
|
|
echo >&2 "$msg"
|
|
}
|
|
|
|
# Simplified version of die that should be called by functions that
|
|
# could fail as part of the normal "die()" code path. Required to
|
|
# avoid infinite recursion.
|
|
_fatal()
|
|
{
|
|
local msg="$*"
|
|
|
|
echo >&2 "FATAL: $msg"
|
|
exit 1
|
|
}
|
|
|
|
# Canonicalize the specified path (which must be valid).
|
|
resolve_path()
|
|
{
|
|
local file="${1:-}"
|
|
[ -z "$file" ] && _fatal "need file to resolve"
|
|
|
|
local path
|
|
|
|
path=$(readlink --canonicalize-existing "$file" || \
|
|
_fatal "failed to resolve file '$file'")
|
|
|
|
echo "$path"
|
|
}
|
|
|
|
show_proc_hierarchy()
|
|
{
|
|
local pid="${$}"
|
|
|
|
local details
|
|
|
|
stderr "process-hierarchy:"
|
|
|
|
local -i i
|
|
|
|
for ((i=0; ; i++))
|
|
do
|
|
local details
|
|
local msg
|
|
|
|
local current=''
|
|
|
|
[ "${pid}" = "${$}" ] && current=", current='yes'"
|
|
|
|
details=$(ps --no-headers -p "$pid" -o ppid,cmd)
|
|
|
|
# The parent PID is always the first column due to the
|
|
# format specifier used above.
|
|
local ppid=$(echo "$details" | awk '{print $1}')
|
|
|
|
# But the command part has a variable number of fields
|
|
# (since it could contain any number of spaces).
|
|
# Hence, delete the first field (PPID) and what
|
|
# remains is the entire command line.
|
|
local cmd=$(echo "$details" |\
|
|
awk '{$1=""; print $0}' |\
|
|
sed \
|
|
-e 's/^ *//g' \
|
|
-e 's/ *$//g')
|
|
|
|
msg=$(printf " %d: {pid: %d, command: '%s'%s}" \
|
|
"${i}" \
|
|
"${pid}" \
|
|
"${cmd}" \
|
|
"${current}")
|
|
stderr "$msg"
|
|
|
|
[ "$pid" = 1 ] && break
|
|
|
|
pid="$ppid"
|
|
done
|
|
}
|
|
|
|
show_stacktrace()
|
|
{
|
|
local err_line="${1:-}"
|
|
local err_func="${2:-}"
|
|
local err_path="${3:-}"
|
|
|
|
[ -z "$err_line" ] && _fatal "need error location line number"
|
|
[ -z "$err_func" ] && _fatal "need error location func"
|
|
[ -z "$err_path" ] && _fatal "need error location file path"
|
|
|
|
local line
|
|
local func
|
|
local file
|
|
|
|
local -i i
|
|
|
|
stderr "stacktrace:"
|
|
|
|
for ((i = 0; ; i++))
|
|
do
|
|
local result
|
|
result=$(caller "$i" || true)
|
|
|
|
[ -z "$result" ] && break
|
|
|
|
line=$(echo "$result"|awk '{print $1}')
|
|
func=$(echo "$result"|awk '{print $2}')
|
|
file=$(echo "$result"|awk '{print $3}')
|
|
|
|
local path
|
|
path=$(resolve_path "$file")
|
|
|
|
local msg
|
|
|
|
local current=''
|
|
|
|
# Add a visual marker showing where the original error was
|
|
# detected.
|
|
[ "${line}" = "${err_line}" ] && \
|
|
[ "${func}" = "${err_func}" ] && \
|
|
[ "${path}" = "${err_path}" ] && \
|
|
current=", current='yes'"
|
|
|
|
msg=$(printf " %d: {function: '%s', file: '%s', line: %d%s}\n" \
|
|
"${i}" \
|
|
"${func}" \
|
|
"${path}" \
|
|
"${line}" \
|
|
"${current}" )
|
|
|
|
stderr "$msg"
|
|
done
|
|
}
|
|
|
|
# Function to be called by die() or a trap/signal handler to dump all
|
|
# details of the environment (in YAML format), to help with debugging.
|
|
dump_details()
|
|
{
|
|
set +x
|
|
|
|
local err_line="${1:-}"
|
|
local err_func="${2:-}"
|
|
local err_path="${3:-}"
|
|
|
|
[ -z "$err_line" ] && _fatal "need error location line number"
|
|
[ -z "$err_func" ] && _fatal "need error location func"
|
|
[ -z "$err_path" ] && _fatal "need error location file path"
|
|
|
|
# Spacer
|
|
stderr
|
|
|
|
stderr "script:"
|
|
stderr " name: '$0'"
|
|
stderr " pid: $$"
|
|
stderr " directory: '$PWD'"
|
|
stderr " details: '$(ls -dlZ "$PWD")'"
|
|
stderr "failure:"
|
|
stderr " function: '$func'"
|
|
stderr " file: '$path'"
|
|
stderr " line: $line"
|
|
stderr " name: '$0'"
|
|
|
|
show_stacktrace \
|
|
"${err_line}" \
|
|
"${err_func}" \
|
|
"${err_path}"
|
|
|
|
show_proc_hierarchy
|
|
|
|
stderr "time: '$(date -Isec)'"
|
|
stderr "runtime-seconds: ${SECONDS}"
|
|
stderr "host:"
|
|
stderr " name: '$(hostname)'"
|
|
stderr " uname: '$(uname -a)'"
|
|
|
|
stderr "locale:"
|
|
locale 2>/dev/null | sed \
|
|
-e 's/^/ /g' \
|
|
-e 's/=/: '\''/g' \
|
|
-e 's/$/'\''/g' \
|
|
>&2
|
|
|
|
stderr "user:"
|
|
stderr " uid: {value: $UID, name: '$(getent passwd "$UID"|cut -d: -f1)'}"
|
|
stderr " euid: {value: $EUID , name: '$(getent passwd "$EUID"|cut -d: -f1)'}"
|
|
stderr " groups: '$(id)'"
|
|
|
|
stderr "bash:"
|
|
stderr " version: '${BASH_VERSION}'"
|
|
stderr " version-info: '${BASH_VERSINFO[*]}'"
|
|
|
|
stderr "environment:"
|
|
|
|
# Remove bash functions (that can span multiple lines)
|
|
env |\
|
|
grep -v "^BASH_FUNC" |\
|
|
grep -Ei "^[a-z_][a-z0-9_]+=" |\
|
|
sort -t '=' -k1 |\
|
|
sed \
|
|
-e 's/^/ /g' \
|
|
-e 's/=/: '\''/' \
|
|
-e 's/$/'\''/g' \
|
|
>&2
|
|
|
|
stderr "mounts: |"
|
|
mount | sed 's/^/ /g' >&2
|
|
|
|
stderr "processes: |"
|
|
ps -eF | sed 's/^/ /g' >&2
|
|
|
|
# Spacer
|
|
stderr
|
|
}
|