all lists on 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 an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.
Service provided by Proxmox Server Solutions GmbH | Privacy | Legal