From af89baf21db5d665698503102cd89fa625ea64ae Mon Sep 17 00:00:00 2001 From: Ali Mirjamali Date: Fri, 27 Sep 2024 15:37:35 +0330 Subject: [PATCH] Fix DNF5 repoquery related: https://github.com/QubesOS/qubes-core-admin-client/pull/308 --- qubes-rpc/qvm-template-repo-query | 41 ++++++++++++++++++++++++++----- 1 file changed, 35 insertions(+), 6 deletions(-) mode change 100755 => 100644 qubes-rpc/qvm-template-repo-query diff --git a/qubes-rpc/qvm-template-repo-query b/qubes-rpc/qvm-template-repo-query old mode 100755 new mode 100644 index 2e78cb7c..8e7bd9c4 --- a/qubes-rpc/qvm-template-repo-query +++ b/qubes-rpc/qvm-template-repo-query @@ -26,11 +26,18 @@ repodir=$(mktemp -d) trap 'rm -r "$repodir"' EXIT cat > "$repodir/template.repo" +DNF5=false +if [ "$(readlink /usr/bin/dnf)" = "dnf5" ]; then + DNF5=true +fi + OPTS+=(-y "--setopt=reposdir=${repodir}" --quiet) -# use vendored 'downloadurl' dnf-plugin (fork of 'download' plugin), to print -# all mirrors -OPTS+=("--setopt=pluginpath=/usr/lib/qubes/dnf-plugins") +if ! $DNF5; then + # use vendored 'downloadurl' dnf-plugin (fork of 'download' plugin), to print + # all mirrors + OPTS+=("--setopt=pluginpath=/usr/lib/qubes/dnf-plugins") +fi if ! command -v dnf >/dev/null; then echo "ERROR: dnf command is missing, please use newer template for your UpdateVM to download templates." >&2 @@ -49,7 +56,11 @@ touch -r "$hashfile" "$repodir/template.repo" RET=0 if [ "$1" = "query" ]; then - dnf repoquery "${OPTS[@]}" --qf='%{name}|%{epoch}|%{version}|%{release}|%{reponame}|%{downloadsize}|%{buildtime}|%{license}|%{url}|%{summary}|%{description}|' "$SPEC" + if $DNF5; then + dnf repoquery "${OPTS[@]}" --qf='%{name}|%{epoch}|%{version}|%{release}|%{repoid}|%{downloadsize}|%{buildtime}|%{license}|%{url}|%{summary}|%{description}|\n' "$SPEC" + else + dnf repoquery "${OPTS[@]}" --qf='%{name}|%{epoch}|%{version}|%{release}|%{repoid}|%{downloadsize}|%{buildtime}|%{license}|%{url}|%{summary}|%{description}|' "$SPEC" + fi RET="$?" elif [ "$1" = "download" ]; then # Download/retry algorithm: take mirrors in random order. In this order, @@ -57,8 +68,26 @@ elif [ "$1" = "download" ]; then # downloaded - retry from the same one. If download failed and nothing was # downloaded, go to the next one. The intention is to retry on interrupted # connection, but skip mirrors that are not synchronized yet. - urls="$(dnf downloadurl "${OPTS[@]}" --url --all-mirrors "$SPEC" | shuf)" - readarray -t urls <<<"$urls" + declare -a urls=() + if $DNF5 && dnf download --help | grep -q allmirrors; then + # The smartest case. DNF5 on Fedora 41 with --allmirrors patch + space_separated_urls="$(dnf download "${OPTS[@]}" --url --allmirrors "$SPEC")" + readarray -d ' ' -t urls <<<"$space_separated_urls" + urls=( $(shuf -e "${urls[@]}") ) + elif $DNF5; then + # The middle case. DNF5 on Fedora 41 before --allmirror patch + # TODO: Phase out after DNF5 --allmirrors patch is released + url="$(dnf download "${OPTS[@]}" --url "$SPEC")" + urls+=($url) + else + # The old DNF4 on Fedora 40 and other old templates + # use vendored 'downloadurl' dnf-plugin (fork of 'download' plugin), + # to print all mirrors. + # TODO: Phase out after DNF4 is EOL + OPTS+=("--setopt=pluginpath=/usr/lib/qubes/dnf-plugins") + urls="$(dnf downloadurl "${OPTS[@]}" --url --all-mirrors "$SPEC" | shuf)" + readarray -t urls <<<"$urls" + fi downloaded=0 status_file="$repodir/download-status.tmp" for url in "${urls[@]}"; do