public inbox for pve-devel@lists.proxmox.com
 help / color / mirror / Atom feed
From: Christoph Heiss <c.heiss@proxmox.com>
To: pve-devel@lists.proxmox.com
Subject: [pve-devel] [PATCH installer 1/2] auto: answer: add option to poweroff the machine instead of reboot
Date: Mon, 31 Mar 2025 14:20:04 +0200	[thread overview]
Message-ID: <20250331122018.740427-2-c.heiss@proxmox.com> (raw)
In-Reply-To: <20250331122018.740427-1-c.heiss@proxmox.com>

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>
---
 proxmox-auto-installer/src/answer.rs          | 10 ++++++
 .../src/bin/proxmox-auto-installer.rs         | 12 ++++++-
 proxmox-low-level-installer                   |  3 +-
 unconfigured.sh                               | 31 ++++++++++++++++---
 4 files changed, 49 insertions(+), 7 deletions(-)

diff --git a/proxmox-auto-installer/src/answer.rs b/proxmox-auto-installer/src/answer.rs
index c11818e..c15016f 100644
--- a/proxmox-auto-installer/src/answer.rs
+++ b/proxmox-auto-installer/src/answer.rs
@@ -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 {
diff --git a/proxmox-auto-installer/src/bin/proxmox-auto-installer.rs b/proxmox-auto-installer/src/bin/proxmox-auto-installer.rs
index 0f86af0..05d1801 100644
--- a/proxmox-auto-installer/src/bin/proxmox-auto-installer.rs
+++ b/proxmox-auto-installer/src/bin/proxmox-auto-installer.rs
@@ -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.");
diff --git a/proxmox-low-level-installer b/proxmox-low-level-installer
index bcfe60e..9d5d0a2 100755
--- a/proxmox-low-level-installer
+++ b/proxmox-low-level-installer
@@ -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;
 	}
diff --git a/unconfigured.sh b/unconfigured.sh
index a5621a0..4d641b2 100755
--- a/unconfigured.sh
+++ b/unconfigured.sh
@@ -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
 
-- 
2.48.1



_______________________________________________
pve-devel mailing list
pve-devel@lists.proxmox.com
https://lists.proxmox.com/cgi-bin/mailman/listinfo/pve-devel


  reply	other threads:[~2025-03-31 12:21 UTC|newest]

Thread overview: 4+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2025-03-31 12:20 [pve-devel] [PATCH installer 0/2] auto: add option to poweroff system after installation Christoph Heiss
2025-03-31 12:20 ` Christoph Heiss [this message]
2025-03-31 12:20 ` [pve-devel] [PATCH installer 2/2] post-hook: add `reboot_mode` field Christoph Heiss
2025-04-04  9:04 ` [pve-devel] applied-series: [PATCH installer 0/2] auto: add option to poweroff system after installation Thomas Lamprecht

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=20250331122018.740427-2-c.heiss@proxmox.com \
    --to=c.heiss@proxmox.com \
    --cc=pve-devel@lists.proxmox.com \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox
Service provided by Proxmox Server Solutions GmbH | Privacy | Legal