Skip to content

SSH-based guest check always fails: extra "bash -c" breaks the remote count command (apt and rpm paths) #342

Description

@bwernli

Describe the bug
Every VM checked over the SSH path fails with APT_COUNT_UNAVAILABLE,
regardless of the guest:

CHECK 100 · guest-a failed: APT_COUNT_UNAVAILABLE - Could not determine APT update counts for VM 100
CHECK 101 · guest-b failed: APT_COUNT_UNAVAILABLE - APT update count metadata is unavailable for VM 101

APT_COUNT_REMOTE_COMMAND already builds a complete command
(python3 -c <base64 payload>), but the SSH call wraps it in another
bash -c (check-updates.sh line 1649):

APT_OUTPUT=$(RUN_SSH_COMMAND "$IP" "$SSH_VM_PORT" "$USER" bash -c "$apt_count_command")

RUN_SSH_COMMAND passes "$@" straight to ssh (line 96-100), and ssh joins
its arguments into a single string that the remote login shell re-splits. The
guest therefore receives:

bash -c python3 -c import\ base64\;exec\(base64.b64decode\(...\)\)

bash -c takes only the first word as the command, so it runs bare python3
and assigns the rest to $0, $1, ... With no -c argument python3 reads
from stdin and blocks until timeout 15 in RUN_SSH_COMMAND kills it.

Depending on where it is killed the run produces either a non-zero exit
("Could not determine APT update counts") or empty output that fails
PARSE_APT_UPDATE_COUNTS ("APT update count metadata is unavailable") - two
different messages, one cause.

To Reproduce
Minimal, outside the updater (CMD built exactly as APT_COUNT_REMOTE_COMMAND does):

CMD=$(printf 'python3 -c %q' "import base64;exec(base64.b64decode('$(base64 -w0 /etc/ultimate-updater/apt-count.py)'))")

ssh -o BatchMode=yes root@<guest-ip> bash -c "$CMD" < /dev/null; echo "RC=$?"
# -> no output, RC=0   (without </dev/null it hangs)

ssh -o BatchMode=yes root@<guest-ip> "$CMD"; echo "RC=$?"
# -> APT_COUNTS|0|0|0|true
# -> RC=0

The QGA path (line ~1925) uses the same bash -c wrapper but works, because
qm guest exec passes a real argument array instead of a string going through
a second shell. Only the SSH path is affected.

Expected behavior
VMs reachable over SSH report their update counts like QGA guests do.

Suggested fix
Drop the redundant bash -c, since the helper already emits a full command:

APT_OUTPUT=$(RUN_SSH_COMMAND "$IP" "$SSH_VM_PORT" "$USER" "$apt_count_command")

Verified locally on two VMs, both previously failing:

CHECK 100 · guest-a completed: 0 updates available   EXIT=0
CHECK 101 · guest-b completed: 6 updates available   EXIT=0

The RPM path has the same construct and is presumably affected in the same way
(untested here, no RPM-based guests):

check-updates.sh:1680  RUN_SSH_COMMAND "$IP" "$SSH_VM_PORT" "$USER" bash -c "$rpm_count_command"
check-updates.sh:1730  RUN_SSH_COMMAND "$IP" "$SSH_VM_PORT" "$USER" bash -c "$rpm_count_command"

All three occurrences are still present on beta as of the commit below.

VM/LXC (please complete the following information):
Debian-based VMs checked over SSH (no QEMU guest agent running).

Used Version
Branch: beta (5.1.3, commit 4bd6563)

Installed commit: 4bd6563affe3542110ddf9c775da407f134103bf
Available commit: 4bd6563affe3542110ddf9c775da407f134103bf
Installed tag: —

Component    Local     Server
---------    -----     ------
Updater      5.1.3     5.1.3
Extras       3.1       3.1
Config       2.1       2.1
Welcome      3.0       3.0
Check        2.1       2.1

Additional context
Introduced with the new apt-count.py / rpm-count.py / package-count.sh helpers.
Separate code path from #338.

Activity

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Labels

    bugSomething isn't workingdevelopmentunder development

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions