B #231: Workaround the mawk issue on Debian

The default 'awk' _alternative_ on the Debian is an old mawk of version
1.3.3 with plenty of bugs and problems. One of them is the lack of
support for POSIX regex character classes which old mawk does not know
despite the fact that it does advertise a support for extended regex (as
egrep for example).

This was reported and fixed in 2009 with version of 1.3.4 but Debian is
still using the old unfixed version 1.3.3:
https://bugs.launchpad.net/ubuntu/+source/mawk/+bug/69724

This commit workaround this issue by simple test and possible abort if
the usage of an incompatible awk implementation is unreasonable - user
choice.

Note: Currently just only two optional (non-default) tests are skipped
due to this issue.

Signed-off-by: Petr Ospalý <pospaly@opennebula.io>
pull/235/head
Petr Ospalý 4 years ago committed by Vlastimil Holer
parent 86f639b670
commit 45a8bdb39b

@ -291,6 +291,23 @@ run_cmd()
fi fi
} }
# trivial test of awk command capabilities and compliance - it will output
# either YES or NO
is_awk_correct()
(
_awk_result=$(echo 'abcABC xyz123.' | awk '
{
sub(/[[:upper:]]+[[:space:]]+[[:alnum:]]+/, "");
print;
}')
if [ "${_awk_result}" = 'abc.' ] ; then
echo 'YES'
else
echo 'NO'
fi
)
# arg: [normal|summary] # arg: [normal|summary]
# if used with argument 'summary' then it will print out summary of supported # if used with argument 'summary' then it will print out summary of supported
# operations - otherwise it will output parseable: <op>:<default> # operations - otherwise it will output parseable: <op>:<default>
@ -306,16 +323,16 @@ parse_sysprep_operations()
next; next;
op = $1; op = $1;
sub(/^[[:space:]]*/, "", op); sub(/^[ ]*/, "", op);
sub(/[[:space:]]*$/, "", op); sub(/[ ]*$/, "", op);
default_op = $2; default_op = $2;
sub(/^[[:space:]]*/, "", default_op); sub(/^[ ]*/, "", default_op);
sub(/[[:space:]]*$/, "", default_op); sub(/[ ]*$/, "", default_op);
comment = $3; comment = $3;
sub(/^[[:space:]]*/, "", comment); sub(/^[ ]*/, "", comment);
sub(/[[:space:]]*$/, "", comment); sub(/[ ]*$/, "", comment);
count++; count++;
ops[count] = op; ops[count] = op;
@ -452,6 +469,19 @@ get_operations()
esac esac
) )
sanity_check()
{
# test the sanity of an awk implementation
_ONE_VALID_AWK=$(is_awk_correct)
export _ONE_VALID_AWK
if [ "${_ONE_VALID_AWK}" = 'NO' ] ; then
warn "The currently used awk command does not support POSIX:"
printf "\n%s\n\n" "$(awk -W version 2>&1 || true)"
printf "[!] NOTE: Install an alternative (e.g. gawk) or some operations may be skipped!\n\n"
fi
}
# this will try to guess the system it is running on and if it is supported by # this will try to guess the system it is running on and if it is supported by
# this script # this script
syscheck() syscheck()
@ -661,6 +691,7 @@ parse_password_arguments()
} }
# arg: <length> # arg: <length>
# shellcheck disable=SC2120
gen_password() gen_password()
{ {
pw_length="${1:-16}" pw_length="${1:-16}"
@ -671,15 +702,17 @@ gen_password()
new_pw=$(pwgen -s "${pw_length}" 1) new_pw=$(pwgen -s "${pw_length}" 1)
break break
elif command -v openssl >/dev/null ; then elif command -v openssl >/dev/null ; then
# shellcheck disable=SC2086
new_pw="${new_pw}$(openssl rand -base64 ${pw_length} | tr -dc '[:alnum:]')" new_pw="${new_pw}$(openssl rand -base64 ${pw_length} | tr -dc '[:alnum:]')"
else else
new_pw="${new_pw}$(head /dev/urandom | tr -dc '[:alnum:]')" new_pw="${new_pw}$(head /dev/urandom | tr -dc '[:alnum:]')"
fi fi
# shellcheck disable=SC2000 # shellcheck disable=SC2000
# shellcheck disable=SC2086
[ "$(echo $new_pw | wc -c)" -ge "$pw_length" ] && break [ "$(echo $new_pw | wc -c)" -ge "$pw_length" ] && break
done done
echo "$new_pw" | cut -c1-${pw_length} echo "$new_pw" | cut -c1-"${pw_length}"
} }
# arg: <user:locked:disabled:file:password:random:value...> # arg: <user:locked:disabled:file:password:random:value...>
@ -963,17 +996,34 @@ run_ops()
"Run operation" "Run operation"
printf " ${SETCOLOR_ON_COMMAND}%s${SETCOLOR_OFF}\n" \ printf " ${SETCOLOR_ON_COMMAND}%s${SETCOLOR_OFF}\n" \
"${_op}" "${_op}"
# if-wrap
if eval "op_${_op_func}" ; then if eval "op_${_op_func}" ; then
printf "${SETCOLOR_ON_HIGHLIGHT}%s${SETCOLOR_OFF}" \ _op_func_return_code=$?
"Result"
printf " ... ${SETCOLOR_ON_OK}%s${SETCOLOR_OFF}\n\n" \
"OK"
else else
printf "${SETCOLOR_ON_HIGHLIGHT}%s${SETCOLOR_OFF}" \ _op_func_return_code=$?
"Result"
printf " ... ${SETCOLOR_ON_FAILURE}%s${SETCOLOR_OFF}\n\n" \
"FAILED"
fi fi
case "${_op_func_return_code}" in
0)
printf "${SETCOLOR_ON_HIGHLIGHT}%s${SETCOLOR_OFF}" \
"Result"
printf " ... ${SETCOLOR_ON_OK}%s${SETCOLOR_OFF}\n\n" \
"OK"
;;
1)
printf "${SETCOLOR_ON_HIGHLIGHT}%s${SETCOLOR_OFF}" \
"Result"
printf " ... ${SETCOLOR_ON_FAILURE}%s${SETCOLOR_OFF}\n\n" \
"FAILED"
;;
2)
printf "${SETCOLOR_ON_HIGHLIGHT}%s${SETCOLOR_OFF}" \
"Result"
printf " ... ${SETCOLOR_ON_FAILURE}%s${SETCOLOR_OFF}\n\n" \
"SKIPPED"
;;
esac
else else
# run non-verbosely # run non-verbosely
printf "${SETCOLOR_ON_HIGHLIGHT}%s${SETCOLOR_OFF}:" \ printf "${SETCOLOR_ON_HIGHLIGHT}%s${SETCOLOR_OFF}:" \
@ -981,14 +1031,30 @@ run_ops()
printf " ${SETCOLOR_ON_COMMAND}%-*s${SETCOLOR_OFF} ... " \ printf " ${SETCOLOR_ON_COMMAND}%-*s${SETCOLOR_OFF} ... " \
"$_max_oplength" \ "$_max_oplength" \
"${_op}" "${_op}"
# if-wrap
if _op_func_output=$(eval "op_${_op_func}" 2>&1) ; then if _op_func_output=$(eval "op_${_op_func}" 2>&1) ; then
# shellcheck disable=SC2059 _op_func_return_code=$?
printf "${SETCOLOR_ON_OK}OK${SETCOLOR_OFF}\n"
else else
# shellcheck disable=SC2059 _op_func_return_code=$?
printf "${SETCOLOR_ON_FAILURE}FAILED${SETCOLOR_OFF}\n"
echo "$_op_func_output"
fi fi
case "${_op_func_return_code}" in
0)
# shellcheck disable=SC2059
printf "${SETCOLOR_ON_OK}OK${SETCOLOR_OFF}\n"
;;
1)
# shellcheck disable=SC2059
printf "${SETCOLOR_ON_FAILURE}FAILED${SETCOLOR_OFF}\n"
echo "$_op_func_output"
;;
2)
# shellcheck disable=SC2059
printf "${SETCOLOR_ON_FAILURE}SKIPPED${SETCOLOR_OFF}\n"
echo "$_op_func_output"
;;
esac
fi fi
done done
} }
@ -1616,6 +1682,11 @@ op_user_account()
( (
run_op() { echo "+ ${*}" ; "$@" ; } run_op() { echo "+ ${*}" ; "$@" ; }
if [ "${_ONE_VALID_AWK}" = 'NO' ] ; then
printf "[!] This test is skipped due to the incompatible awk implementation!\n"
return 2
fi
# comb the list # comb the list
_keep_list=$(echo "$ARG_USERS_KEEP" | \ _keep_list=$(echo "$ARG_USERS_KEEP" | \
sed -e 's/,/ /g' -e 's/[[:space:]]\+/\n/g' -e '/^$/d' | \ sed -e 's/,/ /g' -e 's/[[:space:]]\+/\n/g' -e '/^$/d' | \
@ -1771,6 +1842,11 @@ op_one_group_account()
( (
run_op() { echo "+ ${*}" ; "$@" ; } run_op() { echo "+ ${*}" ; "$@" ; }
if [ "${_ONE_VALID_AWK}" = 'NO' ] ; then
printf "[!] This test is skipped due to the incompatible awk implementation!\n"
return 2
fi
case "$(uname | tr '[:upper:]' '[:lower:]')" in case "$(uname | tr '[:upper:]' '[:lower:]')" in
linux) linux)
if [ -f /etc/login.defs ] ; then if [ -f /etc/login.defs ] ; then
@ -2012,6 +2088,8 @@ op_one_trim()
# improvement for the future... # improvement for the future...
#msg "Trim/discard the unused space" #msg "Trim/discard the unused space"
# TODO: check awk sanity if used...
#if command -v trim > /dev/null ; then #if command -v trim > /dev/null ; then
# _devs=$(< /etc/fstab awk ' # _devs=$(< /etc/fstab awk '
# { # {
@ -2204,6 +2282,8 @@ ARG_PASSWORD=$(parse_password_arguments "$ARG_PASSWORD")
# execute the requested action # execute the requested action
case "$action" in case "$action" in
'') '')
sanity_check
# ask before running # ask before running
ask_to_run_sysprep ask_to_run_sysprep
@ -2220,6 +2300,8 @@ case "$action" in
exit 0 exit 0
;; ;;
operations) operations)
sanity_check
# ask before running # ask before running
ask_to_run_sysprep ask_to_run_sysprep

Loading…
Cancel
Save