@@ -168,24 +168,74 @@ if [ "$UPDATE_ACTION" = "download" ]; then
168168fi
169169
170170set -e
171+ set -o pipefail
171172
172- " ${UPDATE_COMMAND[@]} " " ${OPTS[@]} " " ${PKGLIST[@]} "
173+ " ${UPDATE_COMMAND[@]} " " ${OPTS[@]} " " ${PKGLIST[@]} " | \
174+ tee " $DOM0_UPDATES_DIR /download.out"
173175
176+ # Collect rpms from various download locations into one directory
174177find " $DOM0_UPDATES_DIR /var/cache" -name ' *.rpm' -print0 2> /dev/null | \
175178 xargs -0 -r ln -f -t " $DOM0_UPDATES_DIR /packages/"
176179
177- if ls " $DOM0_UPDATES_DIR " /packages/* .rpm > /dev/null 2>&1 ; then
180+ case " $UPDATE_ACTION " in
181+ # Never send package to dom0 for the following commands. This by no
182+ # means is an exhaustive list, just some common ones.
183+ changelog|list|search) ;;
184+ # TODO: Look for any other commands that download packages to add and
185+ distro-sync|downgrade|download|install|upgrade)
186+ RPMS=$(
187+ grep ' ^ ' " $DOM0_UPDATES_DIR /download.out" |
188+ tail -n +2 |
189+ while read -r PKG ARCH VER _REPO _SIZE; do
190+ # Assumption: Package names do not contain spaces
191+ F=" $PKG -${VER##*: } .$ARCH .rpm"
192+ if [ -f " $DOM0_UPDATES_DIR " /packages/" $F " ]; then
193+ echo " $F "
194+ else
195+ # Did not find package that was supposed to be downloaded... bail
196+ echo " Package $F requested but not downloaded" >&2
197+ exit 1
198+ fi
199+ done
200+ ) || RET=$?
201+ if [ -z " $RPMS " ]; then
202+ cat >&2 << EOF
203+ No packages found in output for action $UPDATE_ACTION . This is likely
204+ due to a change in the output format. Falling back to old method that
205+ sends all verified packages in the package cache.
206+ Output:
207+ EOF
208+ cat " $DOM0_UPDATES_DIR /download.out" >&2
209+ fi
210+ if [ " ${RET:- 0} " -ne 0 ]; then
211+ # An error occured in determining or finding requested packages,
212+ # unset RPM to fallback to old method.
213+ RPMS=
214+ fi
215+
216+ ;&
217+ # Fallback to previous implementation of uploading all verified rpms
218+ # for all other actions and above failure condition.
219+ * )
220+ if [ -z " $RPMS " ]; then
221+ RPMS=$( for P in " $DOM0_UPDATES_DIR " /packages/* .rpm; do echo ${P##*/ } ; done)
222+ fi
223+ ;;
224+ esac
225+
226+ if [ -n " $RPMS " ]; then
178227 if [ -n " $SIGNATURE_REGEX " ]; then
179228 rpmkeys_error=0
180- for pkg in " $DOM0_UPDATES_DIR " /packages/* .rpm; do
229+ for rpmfile in $RPMS ; do
230+ pkg=" $DOM0_UPDATES_DIR " /packages/" $rpmfile "
181231 rpmkeys_exit_code=0
182232 output=" $( rpmkeys --root " $DOM0_UPDATES_DIR " --checksig " $pkg " ) " \
183233 || rpmkeys_exit_code=" $? "
184234 if [ ! " $rpmkeys_exit_code " = " 0" ]; then
185235 echo " ERROR: could not verify $pkg " >&2
186236 rpmkeys_error=1
187237 rm " $pkg "
188- elif ! echo " $output " | grep -Pq " $SIGNATURE_REGEX " ; then
238+ elif ! echo " $output " | grep -Pq " $SIGNATURE_REGEX " ; then
189239 echo " ERROR: missing or invalid signature for $pkg " >&2
190240 rpmkeys_error=1
191241 rm " $pkg "
@@ -201,11 +251,14 @@ if ls "$DOM0_UPDATES_DIR"/packages/*.rpm > /dev/null 2>&1; then
201251
202252 cmd=" /usr/lib/qubes/qrexec-client-vm dom0 qubes.ReceiveUpdates /usr/lib/qubes/qfile-agent"
203253 qrexec_exit_code=0
204- $cmd " $DOM0_UPDATES_DIR " /packages/* .rpm || { qrexec_exit_code=$? ; true ; };
254+ rpmfiles=$( for rpmfile in $RPMS ; do echo " $DOM0_UPDATES_DIR " /packages/" $rpmfile " ; done)
255+ # shellcheck disable=SC2086
256+ $cmd $rpmfiles || { qrexec_exit_code=$? ; true ; };
205257 if [ ! " $qrexec_exit_code " = " 0" ]; then
206- echo " '$cmd $DOM0_UPDATES_DIR /packages/*.rpm ' failed with exit code ${qrexec_exit_code} !" >&2
258+ echo " '$cmd $rpmfiles ' failed with exit code ${qrexec_exit_code} !" >&2
207259 exit " $qrexec_exit_code "
208260 fi
209261else
210262 echo " No packages downloaded" >&2
211263fi
264+ rm -f " $DOM0_UPDATES_DIR /download.out"
0 commit comments