From mboxrd@z Thu Jan  1 00:00:00 1970
Return-Path: <pve-devel-bounces@lists.proxmox.com>
Received: from firstgate.proxmox.com (firstgate.proxmox.com [IPv6:2a01:7e0:0:424::9])
	by lore.proxmox.com (Postfix) with ESMTPS id 279BE1FF16E
	for <inbox@lore.proxmox.com>; Mon, 31 Mar 2025 14:21:18 +0200 (CEST)
Received: from firstgate.proxmox.com (localhost [127.0.0.1])
	by firstgate.proxmox.com (Proxmox) with ESMTP id 772673097;
	Mon, 31 Mar 2025 14:21:06 +0200 (CEST)
From: Christoph Heiss <c.heiss@proxmox.com>
To: pve-devel@lists.proxmox.com
Date: Mon, 31 Mar 2025 14:20:04 +0200
Message-ID: <20250331122018.740427-2-c.heiss@proxmox.com>
X-Mailer: git-send-email 2.48.1
In-Reply-To: <20250331122018.740427-1-c.heiss@proxmox.com>
References: <20250331122018.740427-1-c.heiss@proxmox.com>
MIME-Version: 1.0
X-SPAM-LEVEL: Spam detection results:  0
 AWL 0.029 Adjusted score from AWL reputation of From: address
 BAYES_00                 -1.9 Bayes spam probability is 0 to 1%
 DMARC_MISSING             0.1 Missing DMARC policy
 KAM_DMARC_STATUS 0.01 Test Rule for DKIM or SPF Failure with Strict Alignment
 RCVD_IN_VALIDITY_CERTIFIED_BLOCKED 0.001 ADMINISTRATOR NOTICE: The query to
 Validity was blocked. See
 https://knowledge.validity.com/hc/en-us/articles/20961730681243 for more
 information.
 RCVD_IN_VALIDITY_RPBL_BLOCKED 0.001 ADMINISTRATOR NOTICE: The query to
 Validity was blocked. See
 https://knowledge.validity.com/hc/en-us/articles/20961730681243 for more
 information.
 RCVD_IN_VALIDITY_SAFE_BLOCKED 0.001 ADMINISTRATOR NOTICE: The query to
 Validity was blocked. See
 https://knowledge.validity.com/hc/en-us/articles/20961730681243 for more
 information.
 SPF_HELO_NONE           0.001 SPF: HELO does not publish an SPF Record
 SPF_PASS               -0.001 SPF: sender matches SPF record
Subject: [pve-devel] [PATCH installer 1/2] auto: answer: add option to
 poweroff the machine instead of reboot
X-BeenThere: pve-devel@lists.proxmox.com
X-Mailman-Version: 2.1.29
Precedence: list
List-Id: Proxmox VE development discussion <pve-devel.lists.proxmox.com>
List-Unsubscribe: <https://lists.proxmox.com/cgi-bin/mailman/options/pve-devel>, 
 <mailto:pve-devel-request@lists.proxmox.com?subject=unsubscribe>
List-Archive: <http://lists.proxmox.com/pipermail/pve-devel/>
List-Post: <mailto:pve-devel@lists.proxmox.com>
List-Help: <mailto:pve-devel-request@lists.proxmox.com?subject=help>
List-Subscribe: <https://lists.proxmox.com/cgi-bin/mailman/listinfo/pve-devel>, 
 <mailto:pve-devel-request@lists.proxmox.com?subject=subscribe>
Reply-To: Proxmox VE development discussion <pve-devel@lists.proxmox.com>
Content-Type: text/plain; charset="us-ascii"
Content-Transfer-Encoding: 7bit
Errors-To: pve-devel-bounces@lists.proxmox.com
Sender: "pve-devel" <pve-devel-bounces@lists.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