Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
5 changes: 5 additions & 0 deletions .github/workflows/verify-split-files.yml
Original file line number Diff line number Diff line change
Expand Up @@ -23,6 +23,7 @@ on:
- "pve/**"
- "incus/**"
- "tests/vm-iso-storage.sh"
- "tests/vm-consoles.sh"
- ".github/workflows/verify-split-files.yml"
push:
branches: [main]
Expand All @@ -37,6 +38,7 @@ on:
- "pve/**"
- "incus/**"
- "tests/vm-iso-storage.sh"
- "tests/vm-consoles.sh"
- ".github/workflows/verify-split-files.yml"
workflow_dispatch:

Expand All @@ -61,6 +63,9 @@ jobs:
- name: ISO storage regression tests
run: bash tests/vm-iso-storage.sh

- name: VM console regression tests
run: bash tests/vm-consoles.sh

- name: Prefetch lists cover every engine file
run: |
set -euo pipefail
Expand Down
22 changes: 22 additions & 0 deletions docs/backends.md
Original file line number Diff line number Diff line change
Expand Up @@ -101,6 +101,28 @@ in what they can actually do:
unset variable, and say once through `msg_warn` that they did nothing. They
do not pretend to have succeeded.

### Cloud image consoles

`vm_enable_consoles` enables both the graphical login on `tty1` and the serial
login on `ttyS0`. Fedora/BLS images use `grubby` to update installed kernel
entries, keeping existing non-graphical console arguments and their baud rates.
Images using `/etc/default/grub` use `update-grub`, `grub2-mkconfig`, or
`grub-mkconfig`, depending on which tool is installed. Regeneration failures
remain visible through the image-preparation warnings. A non-GRUB image without
that configuration is left unchanged.

Kernel, SELinux policy-load and audit messages can appear over an interactive
console because the kernel sends output to its configured `console=` devices.
This is especially visible during package updates and policy reloads; a
policy-load message is not itself an access denial. Console setup does not
disable SELinux, auditing, or lower kernel log verbosity.
For a temporary quieter console, `sudo dmesg -n 5` suppresses kernel notices,
informational and debug messages on the console while keeping warnings/errors
and the kernel log itself. It resets at reboot and does not suppress all
userspace console output.

Run the host-independent bootloader tests with `bash tests/vm-consoles.sh`.

### Proxmox installer ISO storage

Installer VMs call `vm_select_iso_storage "<filename.iso>" [hostname]` before
Expand Down
49 changes: 45 additions & 4 deletions incus/vm-core.func
Original file line number Diff line number Diff line change
Expand Up @@ -1586,10 +1586,51 @@ vm_enable_consoles() {
fi'

_vm_customize "grub console" "$image" --run-command \
'if [ -f /etc/default/grub ]; then
sed -i "s/console=ttyS0[^ \"]*/console=tty1 &/" /etc/default/grub
grep -q "console=tty1" /etc/default/grub || sed -i "s/\(GRUB_CMDLINE_LINUX_DEFAULT=\"\)/\1console=tty1 /" /etc/default/grub
command -v update-grub >/dev/null 2>&1 && update-grub
'set -e
if command -v grubby >/dev/null 2>&1; then
kernel_info=$(grubby --info=DEFAULT)
if ! printf "%s\n" "$kernel_info" | grep -q "^args=\""; then
echo "error: grubby returned no default kernel arguments" >&2
exit 1
fi
all_kernel_info=$(grubby --info=ALL)
if ! printf "%s\n" "$all_kernel_info" | grep -q "^args=\""; then
echo "error: grubby returned no installed kernel arguments" >&2
exit 1
fi
remove_args=$(printf "%s\n" "$all_kernel_info" |
grep "^args=" | grep -o "console=[^ \"]*" |
sed "s/.*/console/" | tr "\n" " ")
console_args=$(printf "%s\n" "$kernel_info" |
grep "^args=" | grep -o "console=[^ \"]*" |
grep -vE "^console=tty[0-9]+(,|$)" | tr "\n" " ")
# Older grubby versions add before removing when both flags share a call.
if [ -n "$remove_args" ]; then
grubby --update-kernel=ALL --remove-args="$remove_args"
fi
grubby --update-kernel=ALL --args="console=tty1 ${console_args:-console=ttyS0,115200}"
elif [ -f /etc/default/grub ]; then
cmdline=GRUB_CMDLINE_LINUX
if ! grep -q "^${cmdline}=\"" /etc/default/grub; then
cmdline=GRUB_CMDLINE_LINUX_DEFAULT
fi
if ! grep -q "^${cmdline}=\"" /etc/default/grub; then
echo "error: No quoted GRUB kernel command line found" >&2
exit 1
fi
if ! grep "^${cmdline}=" /etc/default/grub | grep -Eq "console=tty1([[:space:],\"]|$)"; then
sed -i "s/^${cmdline}=\"/${cmdline}=\"console=tty1 /" /etc/default/grub
fi
if command -v update-grub >/dev/null 2>&1; then
update-grub
elif command -v grub2-mkconfig >/dev/null 2>&1; then
grub2-mkconfig -o /boot/grub2/grub.cfg
elif command -v grub-mkconfig >/dev/null 2>&1; then
grub-mkconfig -o /boot/grub/grub.cfg
else
echo "error: No supported GRUB configuration tool found" >&2
exit 1
fi
fi'
return 0
}
Expand Down
49 changes: 45 additions & 4 deletions pve/vm-core.func
Original file line number Diff line number Diff line change
Expand Up @@ -2039,10 +2039,51 @@ vm_enable_consoles() {
# first and ttyS0 last keeps qm terminal as the primary console while the
# graphical one also shows the boot.
_vm_customize "grub console" "$image" --run-command \
'if [ -f /etc/default/grub ]; then
sed -i "s/console=ttyS0[^ \"]*/console=tty1 &/" /etc/default/grub
grep -q "console=tty1" /etc/default/grub || sed -i "s/\(GRUB_CMDLINE_LINUX_DEFAULT=\"\)/\1console=tty1 /" /etc/default/grub
command -v update-grub >/dev/null 2>&1 && update-grub
'set -e
if command -v grubby >/dev/null 2>&1; then
kernel_info=$(grubby --info=DEFAULT)
if ! printf "%s\n" "$kernel_info" | grep -q "^args=\""; then
echo "error: grubby returned no default kernel arguments" >&2
exit 1
fi
all_kernel_info=$(grubby --info=ALL)
if ! printf "%s\n" "$all_kernel_info" | grep -q "^args=\""; then
echo "error: grubby returned no installed kernel arguments" >&2
exit 1
fi
remove_args=$(printf "%s\n" "$all_kernel_info" |
grep "^args=" | grep -o "console=[^ \"]*" |
sed "s/.*/console/" | tr "\n" " ")
console_args=$(printf "%s\n" "$kernel_info" |
grep "^args=" | grep -o "console=[^ \"]*" |
grep -vE "^console=tty[0-9]+(,|$)" | tr "\n" " ")
# Older grubby versions add before removing when both flags share a call.
if [ -n "$remove_args" ]; then
grubby --update-kernel=ALL --remove-args="$remove_args"
fi
grubby --update-kernel=ALL --args="console=tty1 ${console_args:-console=ttyS0,115200}"
elif [ -f /etc/default/grub ]; then
cmdline=GRUB_CMDLINE_LINUX
if ! grep -q "^${cmdline}=\"" /etc/default/grub; then
cmdline=GRUB_CMDLINE_LINUX_DEFAULT
fi
if ! grep -q "^${cmdline}=\"" /etc/default/grub; then
echo "error: No quoted GRUB kernel command line found" >&2
exit 1
fi
if ! grep "^${cmdline}=" /etc/default/grub | grep -Eq "console=tty1([[:space:],\"]|$)"; then
sed -i "s/^${cmdline}=\"/${cmdline}=\"console=tty1 /" /etc/default/grub
fi
if command -v update-grub >/dev/null 2>&1; then
update-grub
elif command -v grub2-mkconfig >/dev/null 2>&1; then
grub2-mkconfig -o /boot/grub2/grub.cfg
elif command -v grub-mkconfig >/dev/null 2>&1; then
grub-mkconfig -o /boot/grub/grub.cfg
else
echo "error: No supported GRUB configuration tool found" >&2
exit 1
fi
fi'
return 0
}
Expand Down
Loading
Loading