Skip to content

Commit ce7253a

Browse files
committed
Better parsing of command-line options
This makes qubes-dom0-update aware of various command-line options that take arguments, so it can process them accordingly. It is not a perfect solution; that would require using a C wrapper program to reject abbreviated or unknown options. It also uses bash regex matching instead of the `echo | grep` anti-pattern, replaces an `==` with `=`, adds a missing `--`, and unsets a variable that will be checked for being set later. The same approach used here could be used to refactor qubes-gpg-client-wrapper if it were worth the time, which it probably isn’t unless qubes-gpg-client-wrapper will see future use.
1 parent 91fdaa4 commit ce7253a

File tree

1 file changed

+70
-16
lines changed

1 file changed

+70
-16
lines changed

dom0-updates/qubes-dom0-update

Lines changed: 70 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -1,13 +1,12 @@
1-
#!/bin/bash
2-
3-
find_regex_in_args() {
4-
local regex="${1}"
5-
shift 1
6-
7-
for arg in "${@}"; do
8-
if echo "${arg}" | grep -q -e "${regex}"; then
9-
return 0
10-
fi
1+
#!/bin/bash --
2+
set -euo pipefail
3+
shopt -s assoc_expand_once
4+
unset YUM_ACTION UPDATEVM shift_amount
5+
6+
check_template_in_args () {
7+
local pkg
8+
for pkg; do
9+
if [[ "$pkg" =~ ^qubes-template- ]]; then return 0; fi
1110
done
1211

1312
return 1
@@ -57,9 +56,60 @@ TEMPLATE=
5756
TEMPLATE_BACKUP=
5857
FORCE_XEN_UPGRADE=
5958
REBOOT_REQUIRED=
59+
declare -A options_with_args
60+
options_with_args=(
61+
[--action]=
62+
[--advisory]=
63+
[--advisories]=
64+
[--bz]=
65+
[--bzs]=
66+
[--color]=
67+
[--comment]=
68+
[--cve]=
69+
[--cves]=
70+
[--debuglevel]=
71+
[--disableexcludes]=
72+
[--disableexcludepkgs]=
73+
[--disableplugin]=
74+
[--disablerepo]=
75+
[--downloaddir]=
76+
[--destdir]=
77+
[--errorlevel]=
78+
[--enableplugin]=
79+
[--enablerepo]=
80+
[--exclude]=
81+
[--excludepkgs]=
82+
[--forcearch]=
83+
[--installroot]=
84+
[--releasever]=
85+
[--repofrompath]=
86+
[--repo]=
87+
[--repoid]=
88+
[--rpmverbosity]=
89+
[--sec-severity]=
90+
[--secseverity]=
91+
[--setopt]=
92+
)
93+
94+
option_takes_arg () {
95+
[[ "$1" =~ ^-[^dexR]*[dexR]$ ]] || [[ -v options_with_args["$1"] ]]
96+
}
97+
6098
# Filter out some dnf options and collect packages list
6199
while [ $# -gt 0 ]; do
100+
shift_amount=1
101+
if option_takes_arg "$1"; then
102+
if [[ "$#" -lt 2 ]]; then
103+
printf 'Missing argument to %s\n' "$1" >&2
104+
exit 1
105+
fi
106+
shift_amount=2
107+
fi
62108
case "$1" in
109+
--enablerepo|--disablerepo)
110+
UPDATEVM_OPTS+=("$1=$2")
111+
QVMTEMPLATE_OPTS+=("$1=$2")
112+
;;
63113
--enablerepo=*|\
64114
--disablerepo=*)
65115
UPDATEVM_OPTS+=( "$1" )
@@ -92,6 +142,10 @@ while [ $# -gt 0 ]; do
92142
--force-xen-upgrade)
93143
FORCE_XEN_UPGRADE=1
94144
;;
145+
--action=)
146+
YUM_ACTION=$1
147+
UPDATEVM_OPTS+=( "$1=$2" )
148+
;;
95149
--action=*)
96150
YUM_ACTION=${1#--action=}
97151
UPDATEVM_OPTS+=( "$1" )
@@ -105,17 +159,17 @@ while [ $# -gt 0 ]; do
105159
fi
106160
;;
107161
-*)
108-
YUM_OPTS+=( "${1}" )
109-
UPDATEVM_OPTS+=( "$1" )
110-
QVMTEMPLATE_OPTS+=( "$1" )
162+
YUM_OPTS+=( "${@:1:shift_amount}" )
163+
UPDATEVM_OPTS+=( "${@:1:shift_amount}" )
164+
QVMTEMPLATE_OPTS+=( "${@:1:shift_amount}" )
111165
;;
112166
*)
113167
PKGS+=( "${1}" )
114168
UPDATEVM_OPTS+=( "$1" )
115169
: "${YUM_ACTION=install}"
116170
;;
117171
esac
118-
shift
172+
shift "$shift_amount"
119173
done
120174

121175
if [[ "$GUI" = 1 ]]; then
@@ -137,7 +191,7 @@ case ${YUM_ACTION=upgrade} in
137191
esac
138192

139193
# Redirect operations on templates to qvm-template command
140-
if find_regex_in_args '^qubes-template-' "${PKGS[@]}"; then
194+
if check_template_in_args "${PKGS[@]}"; then
141195
if [[ ${#PKGS[@]} -ne 1 ]]; then
142196
echo "ERROR: Specify only one package to reinstall template"
143197
exit 2
@@ -201,7 +255,7 @@ if [ "$GUI" == "1" ]; then
201255
fi
202256

203257
# Do not start VM automatically when running from cron (only checking for updates)
204-
if [ "$CHECK_ONLY" == "1" ] && ! qvm-check -q --running "$UPDATEVM" > /dev/null 2>&1; then
258+
if [ "$CHECK_ONLY" = "1" ] && ! qvm-check -q --running -- "$UPDATEVM" > /dev/null 2>&1; then
205259
echo "ERROR: UpdateVM not running, not starting it in non-interactive mode" >&2
206260
exit 1
207261
fi

0 commit comments

Comments
 (0)