From 24c6e5877e431a7eb1e2b03f7ab783153a9a71eb Mon Sep 17 00:00:00 2001 From: dann frazier Date: Tue, 7 Jan 2025 23:55:05 +0000 Subject: [PATCH 1/3] pipelines: test: ldd-check: factory out test for dynamic objects Error out if ldd was not able to actually reason about whether or not a file is a dynamic object by checking it's error message. Signed-off-by: dann frazier --- pipelines/test/ldd-check.yaml | 15 ++++++++++++++- 1 file changed, 14 insertions(+), 1 deletion(-) diff --git a/pipelines/test/ldd-check.yaml b/pipelines/test/ldd-check.yaml index d5d9169b19c..4f9b302758a 100644 --- a/pipelines/test/ldd-check.yaml +++ b/pipelines/test/ldd-check.yaml @@ -62,6 +62,19 @@ pipeline: fail "$f: missing ${missing# }" } + is_dyn_obj() { + errf="$tmpd/ldd.stderr.$$" + # ldd has this code already, let's not NIH it + # note: the actual ldd check happens in test_file() + if ldd "$1" > /dev/null 2> "$errf"; then + return 0 + fi + if grep -q 'not a dynamic executable' "$errf"; then + return 1 + fi + error "$1: failed to determine if file is a dynamic object: $(< "$errf")" + } + test_files_in() { echo "[ldd-check] Testing binaries in package $pkg" apk info -eq "$pkg" > /dev/null || \ @@ -71,7 +84,7 @@ pipeline: [ -n "$f" ] || continue f="/$f" [ -f "$f" ] || continue - ldd "$f" > /dev/null 2>&1 || continue + is_dyn_obj "$f" || continue test_file "$f" done < "$tmpd/$pkg.list" } From 7132f228ad7d87eabb4b7f9f19e05b040f9e1149 Mon Sep 17 00:00:00 2001 From: Scott Moser Date: Fri, 10 Jan 2025 10:18:34 -0500 Subject: [PATCH 2/3] adjust ldd-check I started down this route just trying to fix 'continue' being called from a function (ratner than return). Then the nerd-snype / odd love for pain in shell hit me. Other things here: 1. just a single call to 'ldd' for each file. 2. if 'insist_dyn' is false, then we will just log a message instead of failing in the following cases: * not a file * does not exist * is not a dynamic executable This allows you to call it on all contents in a package and mostly get the results you want. 3. error if ldd exits other than 1 or 0 , and dump the output. 4. error (which exits immediately) if a package in 'packages' is not installed. 5. Please can we add a way to write pipelines in something else? --- pipelines/test/ldd-check.yaml | 88 +++++++++++++++++++++++------------ 1 file changed, 59 insertions(+), 29 deletions(-) diff --git a/pipelines/test/ldd-check.yaml b/pipelines/test/ldd-check.yaml index 4f9b302758a..754ad5a7ee7 100644 --- a/pipelines/test/ldd-check.yaml +++ b/pipelines/test/ldd-check.yaml @@ -38,64 +38,94 @@ pipeline: passes=0 files="${{inputs.files}}" packages="${{inputs.packages}}" - verbose="${{inputs.verbose}}" - case "$verbose" in + VERBOSE="${{inputs.verbose}}" + case "$VERBOSE" in true|false) :;; - *) error "verbose must be 'true' or 'false'. found '$verbose'";; + *) error "VERBOSE must be 'true' or 'false'. found '$VERBOSE'";; esac [ -n "${files}${packages}" ] || error "No files or packages specified" export LANG=C - test_file() { - outf="$tmpd/out" - [ -e "$f" ] || { fail "$f: does not exist"; continue; } - [ -f "$f" ] || { fail "$f: not a file"; continue; } - ldd "$f" > "$outf" || { fail "$f: ldd exited $?"; continue; } + + vmsg() { + [ "$VERBOSE" = "false" ] || echo "$@" + } + + failormsg() { + local cond="$1" msg="$2" + case "$cond" in + true|false) :;; + *) error "cond=$cond - expected true or false";; + esac + [ "$cond" = "true" ] && fail "$msg" + vmsg "$msg" + } + + check_output() { + local file="$1" outf="$2" errf="$3" missing=$(awk \ - '$0 ~ /=> not found/ { miss = miss " " $1; }; END { printf("%s\n", miss); }' \ - "$outf") || error "$f: parsing with awk failed $?"; - if [ "$verbose" = "true" ]; then + '$0 ~ /=> not found/ { miss = miss " " $1; }; + END { printf("%s\n", miss); }' "$outf") || + error "$f: parsing with awk failed $?"; + if [ "$VERBOSE" = "true" ]; then echo "> $ ldd $f" sed 's,^,> ,' "$outf" fi - [ -z "$missing" ] && { pass "$f"; continue; } - fail "$f: missing ${missing# }" + [ -z "$missing" ] || fail "$f: missing ${missing# }" + pass "$f" } - is_dyn_obj() { - errf="$tmpd/ldd.stderr.$$" - # ldd has this code already, let's not NIH it - # note: the actual ldd check happens in test_file() - if ldd "$1" > /dev/null 2> "$errf"; then + check_file() { + local f="$1" insist_dyn="$2" rc="0" + local outf="$tmpd/ldd.stdout" errf="$tmpd/ldd.sterr" + if [ ! -e "$f" ]; then + failormsg "$insist_dyn" "$f: did not exist" + return 0 + fi + if [ ! -f "$f" ]; then + failormsg "$insist_dyn" "$f: is not a file" return 0 fi - if grep -q 'not a dynamic executable' "$errf"; then - return 1 + + ldd "$f" >$outf 2>$errf || rc=$? + + if [ $rc -eq 1 ]; then + if grep -q 'not a dynamic executable' "$errf"; then + failormsg "$insist_dyn" "$f: not a dynamic exectuable" + return 0 + fi + echo "> $ ldd $f" + sed 's,^,> ,' "$outf" "$errf" + error "$f: ldd exited $rc" + elif [ $rc -ne 0 ]; then + echo "> $ ldd $f" + sed 's,^,> ,' "$outf" "$errf" + error "$1: unexpected exit code $rc" fi - error "$1: failed to determine if file is a dynamic object: $(< "$errf")" + + check_output "$f" "$outf" "$errf" } test_files_in() { + local f="" echo "[ldd-check] Testing binaries in package $pkg" - apk info -eq "$pkg" > /dev/null || \ - { fail "Package $pkg is not installed"; continue; } + apk info -eq "$pkg" > /dev/null || + error "Package $pkg is not installed"; apk info -Lq "$pkg" > "$tmpd/$pkg.list" while read f; do [ -n "$f" ] || continue - f="/$f" - [ -f "$f" ] || continue - is_dyn_obj "$f" || continue - test_file "$f" + check_file "/$f" false done < "$tmpd/$pkg.list" } set -- $files for f in "$@"; do - test_file "$f" + check_file "$f" true done set -- $packages for pkg in "$@"; do test_files_in "$pkg" done - echo "tested $((passes+fails)) files with ldd. $passes passes. $fails fails." + echo "tested $((passes+fails)) files with ldd." \ + "$passes passes. $fails fails." exit $fails From 69f73a83c353e185990e438850681eeaffa657f3 Mon Sep 17 00:00:00 2001 From: dann frazier Date: Sat, 25 Jan 2025 12:37:30 -0700 Subject: [PATCH 3/3] pipelines: test/ldd-check: include 'ldd-check' in summary message Signed-off-by: dann frazier --- pipelines/test/ldd-check.yaml | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/pipelines/test/ldd-check.yaml b/pipelines/test/ldd-check.yaml index 754ad5a7ee7..a64d72c1a54 100644 --- a/pipelines/test/ldd-check.yaml +++ b/pipelines/test/ldd-check.yaml @@ -26,6 +26,7 @@ pipeline: runs: | set +x set -f + info() { echo "INFO[ldd-check]:" "$@"; } error() { echo "ERROR[ldd-check]:" "$@"; exit 1; } fail() { echo "FAIL[ldd-check]:" "$@"; fails=$((fails+1)); } pass() { echo "PASS[ldd-check]:" "$@"; passes=$((passes+1)); } @@ -126,6 +127,6 @@ pipeline: for pkg in "$@"; do test_files_in "$pkg" done - echo "tested $((passes+fails)) files with ldd." \ + info "tested $((passes+fails)) files with ldd." \ "$passes passes. $fails fails." exit $fails