-
-
Notifications
You must be signed in to change notification settings - Fork 64
updater: dom0 non-iteractive updater #191
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Changes from 12 commits
2954f3e
5abf2fb
88fd416
627272f
cf188d7
214f031
31fb3c4
a4ed257
15222c1
a379ed0
69c1a80
a7074f9
4824edd
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
| Original file line number | Diff line number | Diff line change |
|---|---|---|
|
|
@@ -28,6 +28,7 @@ if [ "$1" = "--help" ]; then | |
| echo " --force-xen-upgrade force major Xen upgrade even if some qubes are running" | ||
| echo " --console does nothing; ignored for backward compatibility" | ||
| echo " --show-output does nothing; ignored for backward compatibility" | ||
| echo " --quiet do not print anything to stdout" | ||
| echo " --preserve-terminal does nothing; ignored for backward compatibility" | ||
| echo " --skip-boot-check does not check if /boot & /boot/efi should be mounted" | ||
| echo " --switch-audio-server-to=(pulseaudio|pipewire) switch audio daemon to pipewire or pulseaudio" | ||
|
|
@@ -46,6 +47,7 @@ YUM_OPTS=() | |
| UPDATEVM_OPTS=() | ||
| QVMTEMPLATE_OPTS=() | ||
| GUI= | ||
| PROGRESS_REPORTING= | ||
| CHECK_ONLY= | ||
| CLEAN= | ||
| TEMPLATE= | ||
|
|
@@ -79,6 +81,12 @@ while [ $# -gt 0 ]; do | |
| --show-output) | ||
| # ignore | ||
| ;; | ||
| --quiet) | ||
| exec > /dev/null | ||
| ;; | ||
| --just-print-progress) | ||
| PROGRESS_REPORTING=1 | ||
| ;; | ||
| --check-only) | ||
| CHECK_ONLY=1 | ||
| UPDATEVM_OPTS+=( "$1" ) | ||
|
|
@@ -310,40 +318,111 @@ qvm-run --nogui -q -- "$UPDATEVM" "rm -rf -- '$dom0_updates_dir/etc' '$dom0_upda | |
| exit "$status" | ||
| } | ||
|
|
||
| CMD="/usr/lib/qubes/qubes-download-dom0-updates.sh --doit --nogui" | ||
| QVMRUN_OPTS=(--quiet --filter-escape-chars --nogui --pass-io) | ||
|
|
||
| # We avoid using bash’s own facilities for this, as they produce $'\n'-style | ||
| # strings in certain cases. These are not portable, whereas the string produced | ||
| # by the following is. | ||
| for i in "${UPDATEVM_OPTS[@]}"; do CMD+=" '${i//\'/\'\\\'\'}'"; done | ||
| progress_agent_version="4.3" | ||
|
|
||
| QVMRUN_OPTS=(--quiet --filter-escape-chars --nogui --pass-io) | ||
| if [[ -t 1 ]] && [[ -t 2 ]]; then | ||
| # Use ‘script’ to emulate a TTY, so that we get status bars and other | ||
| # progress output. Since stdout and stderr are both terminals, qvm-run | ||
| # will automatically sanitize them, but we explicitly tell it to anyway | ||
| # as a precaution. | ||
| # | ||
| # We MUST NOT use ‘exec script’ here. That causes ‘script’ to | ||
| # inherit the child processes of the shell. ‘script’ mishandles | ||
| # this and enters an infinite loop. | ||
| CMD="script --quiet --return --command '${CMD//\'/\'\\\'\'}' /dev/null" | ||
| get_base_vm() { | ||
| # Resolve base VM (TemplateVM or StandaloneVM) | ||
| local vm="$1" | ||
| while true; do | ||
| # If it's a TemplateVM or StandaloneVM, stop | ||
| if qvm-check --template "$vm" &>/dev/null || qvm-check --standalone "$vm" &>/dev/null; then | ||
| echo "$vm" | ||
| return | ||
| fi | ||
| # Try to get its template | ||
| vm=$(qvm-prefs "$vm" template 2>/dev/null) || return 1 | ||
| done | ||
| } | ||
| version_check() { | ||
| # Compare version numbers (e.g., 4.2 < 4.3) | ||
| awk 'BEGIN {exit !(ARGV[1] < ARGV[2])}' "$1" "$2" | ||
| } | ||
| base_vm=$(get_base_vm "$UPDATEVM") | ||
| OLD_VERSION=0 | ||
| if [ -n "$base_vm" ]; then | ||
| agent_version=$(qvm-features "$base_vm" qubes-agent-version 2>/dev/null) | ||
|
|
||
| if [ -n "$agent_version" ] && version_check "$agent_version" "$progress_agent_version"; then | ||
| OLD_VERSION=1 | ||
| fi | ||
| fi | ||
|
|
||
| qvm-run "${QVMRUN_OPTS[@]}" -- "$UPDATEVM" "$CMD" < /dev/null | ||
|
|
||
| RETCODE=$? | ||
| if [[ "$REMOTE_ONLY" = '1' ]] || [ "$RETCODE" -ne 0 ]; then | ||
| if [ "$PROGRESS_REPORTING" == "1" ] && [ "$OLD_VERSION" == "0" ]; then | ||
| CMD="/usr/lib/qubes/qubes-download-dom0-updates-init.sh" | ||
|
Member
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. This needs to handle the case of old template too. It's okay to refuse this mode in such a case, but it needs a proper error message instead of a file not found error. Something like "Progress reporting requires updatevm based on a template with Qubes 4.3 packages", or something like this (maybe include template name and/or name of the updatevm?) |
||
| qvm-run "${QVMRUN_OPTS[@]}" -- "$UPDATEVM" "$CMD" || exit 1 | ||
|
|
||
| update_agent_log="/var/log/qubes/qubes-update" | ||
| qvm-run --nogui -q -u root -- "$UPDATEVM" "user=\$(qubesdb-read /default-user) && chown -R -- \"\$user:qubes\" '$update_agent_log'" || exit 1 | ||
|
|
||
| # "--no-cleanup" is needed since fakeroot cannot remove entrypoint | ||
| qubes-vm-update --force-update --targets "$UPDATEVM" --signal-no-updates --just-print-progress --display-name dom0 --download-only --no-cleanup --show-output --log=INFO ; RETCODE=$? | ||
| if [ "${RETCODE-0}" -eq 100 ]; then | ||
| echo "$(hostname):out: Nothing to do." | ||
| echo "$(hostname) done no_updates" >&2 | ||
| exit 100 | ||
| fi | ||
| if [ "${RETCODE-0}" -ne 0 ]; then | ||
| echo "$(hostname) done error" >&2 | ||
| exit "$RETCODE" | ||
| fi | ||
|
|
||
| # qubes-vm-update leaves the downloaded packages with root ownership | ||
| qvm-run --nogui -q -u root -- "$UPDATEVM" "user=\$(qubesdb-read /default-user) && chown -R -- \"\$user:qubes\" '$dom0_updates_dir'" || exit 1 | ||
|
|
||
| CMD="/usr/lib/qubes/qubes-download-dom0-updates-finish.sh" | ||
| qvm-run "${QVMRUN_OPTS[@]}" -- "$UPDATEVM" "$CMD" || exit 1 | ||
| else | ||
| if [ "$PROGRESS_REPORTING" == "1" ] && [ "$OLD_VERSION" == "1" ]; then | ||
| echo "$(hostname):out: Progress reporting requires updateVM based on a template with Qubes 4.3 packages." | ||
| fi | ||
| CMD="/usr/lib/qubes/qubes-download-dom0-updates.sh --doit --nogui" | ||
|
|
||
| # We avoid using bash’s own facilities for this, as they produce $'\n'-style | ||
| # strings in certain cases. These are not portable, whereas the string produced | ||
| # by the following is. | ||
| for i in "${UPDATEVM_OPTS[@]}"; do CMD+=" '${i//\'/\'\\\'\'}'"; done | ||
|
|
||
| if [[ -t 1 ]] && [[ -t 2 ]]; then | ||
| # Use ‘script’ to emulate a TTY, so that we get status bars and other | ||
| # progress output. Since stdout and stderr are both terminals, qvm-run | ||
| # will automatically sanitize them, but we explicitly tell it to anyway | ||
| # as a precaution. | ||
| # | ||
| # We MUST NOT use ‘exec script’ here. That causes ‘script’ to | ||
| # inherit the child processes of the shell. ‘script’ mishandles | ||
| # this and enters an infinite loop. | ||
| CMD="script --quiet --return --command '${CMD//\'/\'\\\'\'}' /dev/null" | ||
| fi | ||
| if [ "$PROGRESS_REPORTING" == "1" ]; then | ||
| qvm-run "${QVMRUN_OPTS[@]}" -- "$UPDATEVM" "$CMD" < /dev/null | sed "s/^/$(hostname):out: /" ; RETCODE=$? | ||
| # "consume" the last empty line | ||
| echo "" | ||
| else | ||
| qvm-run "${QVMRUN_OPTS[@]}" -- "$UPDATEVM" "$CMD" < /dev/null ; RETCODE=$? | ||
| fi | ||
| fi | ||
|
|
||
| if [ "$PROGRESS_REPORTING" == "1" ] && [ "$OLD_VERSION" == "1" ]; then | ||
| echo "$(hostname) updating 50.0" >&2 | ||
| if [ "${RETCODE-0}" -ne 0 ]; then | ||
| echo "$(hostname) done error" >&2 | ||
| exit "$RETCODE" | ||
| fi | ||
| fi | ||
| if [[ "$REMOTE_ONLY" = '1' ]] || [ "${RETCODE-0}" -ne 0 ]; then | ||
| if [ "$CHECK_ONLY" = '1' ]; then | ||
| if [ "$RETCODE" -eq 100 ]; then | ||
| if [ "${RETCODE-0}" -eq 100 ]; then | ||
| echo "There are dom0 updates available" >&2 | ||
| elif [ "$RETCODE" -eq 0 ]; then | ||
| elif [ "${RETCODE-0}" -eq 0 ]; then | ||
| echo "No dom0 updates available" >&2 | ||
| else | ||
| echo "Failed to check for dom0 updates" >&2 | ||
| fi | ||
| fi | ||
| exit $RETCODE | ||
| exit "${RETCODE-0}" | ||
| fi | ||
| # Wait for download completed | ||
| while pidof -x qubes-receive-updates >/dev/null; do sleep 0.5; done | ||
|
|
@@ -401,6 +480,9 @@ elif [ -f /var/lib/qubes/updates/repodata/repomd.xml ]; then | |
| # refresh packagekit metadata, GUI utilities use it | ||
| pkcon refresh force | ||
| $guiapp | ||
| elif [ "$PROGRESS_REPORTING" == 1 ]; then | ||
| # report progress to the user | ||
| qubes-vm-update --no-refresh --targets dom0 --force-update --log=DEBUG --just-print-progress --show-output ; RETCODE=$? | ||
| else | ||
| dnf check-update || | ||
| if [ $? -eq 100 ]; then # Run dnf with options | ||
|
|
@@ -416,9 +498,8 @@ elif [ -f /var/lib/qubes/updates/repodata/repomd.xml ]; then | |
| fi | ||
| fi | ||
| else | ||
| if ! qvm-features dom0 updates-available '' 2>/dev/null; then | ||
| qvm-features dom0 updates-available '' >/dev/null 2>&1 || | ||
| echo "*** WARNING: cannot set feature 'updates-available'" >&2 | ||
| fi | ||
| echo "No updates available" >&2 | ||
| if [ "$GUI" == "1" ]; then | ||
| if [ "$KDE_FULL_SESSION" ]; then | ||
|
|
||
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This breaks salt, see QubesOS/qubes-issues#10543 (comment)
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I believe the easiest way would be to rename this flag,
--silent?There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Sounds good,
--silentis not a valid dnf option, so should be safe.