auto: answer: add option to poweroff the machine instead of reboot

Fixes #5880 [0].

Add a new option `global.reboot_mode` to the answer file, which allows
users to optionally power off the machine after a successful
installation, instead of rebooting.

The option is completely backwards-compatible, i.e. defaults to
"reboot", keeping the current behaviour.

This can be useful for certain scenarios, such as being able to
provision a stack of servers using the auto-installer and afterwards
being able to work on the servers without time pressure, such as e.g.
removing the installation medium, before booting them into the OS for
the first time [1].

[0] https://bugzilla.proxmox.com/show_bug.cgi?id=5880
[1] https://forum.proxmox.com/threads/deploying-multiple-proxmox-host-easily.156129/post-721166

Signed-off-by: Christoph Heiss <c.heiss@proxmox.com>
This commit is contained in:
Christoph Heiss 2025-03-31 14:20:04 +02:00 committed by Thomas Lamprecht
parent 1a584e7300
commit 386c7f8bd4
4 changed files with 49 additions and 7 deletions

View File

@ -56,10 +56,20 @@ pub struct Global {
pub root_password_hashed: Option<String>,
#[serde(alias = "reboot_on_error", default)]
pub reboot_on_error: bool,
#[serde(alias = "reboot_mode", default)]
pub reboot_mode: RebootMode,
#[serde(alias = "root_ssh_keys", default)]
pub root_ssh_keys: Vec<String>,
}
#[derive(Clone, Deserialize, Debug, Default, PartialEq, Eq)]
#[serde(rename_all = "kebab-case", deny_unknown_fields)]
pub enum RebootMode {
#[default]
Reboot,
PowerOff,
}
#[derive(Clone, Deserialize, Debug)]
#[serde(rename_all = "kebab-case", deny_unknown_fields)]
pub struct PostNotificationHookInfo {

View File

@ -17,7 +17,7 @@ use proxmox_installer_common::{
};
use proxmox_auto_installer::{
answer::{Answer, FirstBootHookInfo, FirstBootHookSourceMode},
answer::{Answer, FirstBootHookInfo, FirstBootHookSourceMode, RebootMode},
log::AutoInstLogger,
udevinfo::UdevInfo,
utils::parse_answer,
@ -126,6 +126,16 @@ fn main() -> ExitCode {
}
}
if answer.global.reboot_mode == RebootMode::PowerOff {
if let Err(err) = File::create("/run/proxmox-poweroff-after-install") {
error!("failed to create poweroff-after-install flag-file: {err}");
} else {
info!("Powering off system after successful installation");
}
} else {
info!("Rebooting system after successful installation");
}
match run_installation(&answer, &locales, &runtime_info, &udevadm_info, &setup_info) {
Ok(_) => {
info!("Installation done.");

View File

@ -74,9 +74,10 @@ sub read_and_merge_config {
sub send_reboot_ui_message {
if (Proxmox::Install::Config::get_autoreboot()) {
my $action = -f '/run/proxmox-poweroff-after-install' ? 'powering off' : 'rebooting';
my $secs = 5;
while ($secs > 0) {
Proxmox::UI::finished(1, "Installation finished - auto-rebooting in $secs seconds ..");
Proxmox::UI::finished(1, "Installation finished - auto $action in $secs seconds ..");
sleep 1;
$secs -= 1;
}

View File

@ -1,5 +1,7 @@
#!/bin/bash
reboot_action="reboot"
trap "err_reboot" ERR
# NOTE: we nowadays get exec'd by the initrd's PID 1, so we're the new PID 1
@ -52,9 +54,17 @@ eject_and_reboot() {
umount -l -n /dev
echo "rebooting - please remove the ISO boot media"
sleep 3
reboot -nf
# at this stage, all disks are sync'd & unmounted, so `-n/--no-sync` is safe to use here
if [ "$reboot_action" = "poweroff" ]; then
echo "powering off - please remove the ISO boot media"
sleep 3
poweroff -nf
else
echo "rebooting - please remove the ISO boot media"
sleep 3
reboot -nf
fi
sleep 5
echo "trigger reset system request"
# we do not expect the reboot above to fail, so rather to avoid kpanic when pid 1 exits
@ -103,9 +113,12 @@ real_reboot() {
exit 0 # shouldn't be reached, kernel will panic in that case
}
# reachable through the ERR trap
err_reboot() {
printf "\nInstallation aborted - unable to continue (type exit or CTRL-D to reboot)\n"
# in case of error, always default to rebooting
reboot_action="reboot"
debugsh || true
real_reboot
}
@ -274,6 +287,10 @@ elif [ $start_auto_installer -ne 0 ]; then
err_reboot
fi
fi
if [ -f /run/proxmox-poweroff-after-install ]; then
reboot_action="poweroff"
fi
else
echo "Starting the installer GUI - see tty2 (CTRL+ALT+F2) for any errors..."
xinit -- -dpi "$DPI" -s 0 >/dev/tty2 2>&1
@ -287,7 +304,11 @@ if [ $proxdebug -ne 0 ]; then
debugsh || true
fi
echo "Installation done, rebooting... "
if [ "$reboot_action" = "poweroff" ]; then
echo 'Installation done, powering off...'
else
echo 'Installation done, rebooting...'
fi
killall5 -15