From: "Stefan Sterz" <s.sterz@proxmox.com>
To: "Proxmox VE development discussion" <pve-devel@lists.proxmox.com>
Subject: Re: [pve-devel] [PATCH 1/2] assistant: keep prepared iso bootable on uefi with flash drives
Date: Tue, 30 Apr 2024 11:41:04 +0200 [thread overview]
Message-ID: <D0XCWYADW8SQ.1W8HI4SD4J9NO@proxmox.com> (raw)
In-Reply-To: <20240430085434.86655-1-a.lauterer@proxmox.com>
On Tue Apr 30, 2024 at 10:54 AM CEST, Aaron Lauterer wrote:
> By mapping files into the ISO, the UUID for the partitions change as
> they depend on the timestamp. The result is, that grub cannot find its
> partition anymore and the user ends up on the grub shell.
>
> This only happens when booting from a blockdev in UEFI mode. E.g. a USB
> flash drive. Alternatively one can `dd` the ISO to a small (2GiB) VM
> disk and mark it as the first boot device.
>
> Booting in legacy mode or via CDROM (e.g. pass through via IPMI), it
> worked.
>
> Xorriso can report the commands needed to recreate the source ISO. The
> '-volume_date uuid' is the one needed to override the same UUIDs. We
> therefore read it first from the source iso and pass it as parameter
> whenever we inject a file into the iso.
>
> Signed-off-by: Aaron Lauterer <a.lauterer@proxmox.com>
> ---
> proxmox-auto-install-assistant/src/main.rs | 44 ++++++++++++++++++++--
> 1 file changed, 41 insertions(+), 3 deletions(-)
>
> diff --git a/proxmox-auto-install-assistant/src/main.rs b/proxmox-auto-install-assistant/src/main.rs
> index 0debd29..e9213f7 100644
> --- a/proxmox-auto-install-assistant/src/main.rs
> +++ b/proxmox-auto-install-assistant/src/main.rs
> @@ -276,6 +276,7 @@ fn show_system_info(_args: &CommandSystemInfo) -> Result<()> {
>
> fn prepare_iso(args: &CommandPrepareISO) -> Result<()> {
> check_prepare_requirements(args)?;
> + let uuid = get_iso_uuid(&args.input)?;
>
> if args.fetch_from == FetchAnswerFrom::Iso && args.answer_file.is_none() {
> bail!("Missing path to the answer file required for the fetch-from 'iso' mode.");
> @@ -331,10 +332,15 @@ fn prepare_iso(args: &CommandPrepareISO) -> Result<()> {
> instmode_file_tmp.push("auto-installer-mode.toml");
> fs::write(&instmode_file_tmp, toml::to_string_pretty(&config)?)?;
>
> - inject_file_to_iso(&tmp_iso, &instmode_file_tmp, "/auto-installer-mode.toml")?;
> + inject_file_to_iso(
> + &tmp_iso,
> + &instmode_file_tmp,
> + "/auto-installer-mode.toml",
> + &uuid,
> + )?;
>
> if let Some(answer_file) = &args.answer_file {
> - inject_file_to_iso(&tmp_iso, answer_file, "/answer.toml")?;
> + inject_file_to_iso(&tmp_iso, answer_file, "/answer.toml", &uuid)?;
> }
>
> println!("Moving prepared ISO to target location...");
> @@ -371,11 +377,14 @@ fn final_iso_location(args: &CommandPrepareISO) -> PathBuf {
> target.to_path_buf()
> }
>
> -fn inject_file_to_iso(iso: &PathBuf, file: &PathBuf, location: &str) -> Result<()> {
> +fn inject_file_to_iso(iso: &PathBuf, file: &PathBuf, location: &str, uuid: &String) -> Result<()> {
> let result = Command::new("xorriso")
> .arg("--boot_image")
> .arg("any")
> .arg("keep")
> + .arg("-volume_date")
> + .arg("uuid")
> + .arg(uuid)
> .arg("-dev")
> .arg(iso)
> .arg("-map")
> @@ -391,6 +400,35 @@ fn inject_file_to_iso(iso: &PathBuf, file: &PathBuf, location: &str) -> Result<(
> Ok(())
> }
>
> +fn get_iso_uuid(iso: &PathBuf) -> Result<String> {
> + let result = Command::new("xorriso")
> + .arg("-dev")
> + .arg(iso)
> + .arg("-report_system_area")
> + .arg("cmd")
> + .output()?;
> + if !result.status.success() {
> + bail!(
> + "Error determining the UUID of the source ISO: {}",
> + String::from_utf8_lossy(&result.stderr)
> + );
> + }
> + let mut uuid = String::new();
> + for line in String::from_utf8(result.stdout)?.lines() {
> + if line.starts_with("-volume_date uuid") {
> + uuid = line
> + .split(' ')
> + .last()
> + .unwrap()
nit: while this probably won't happen, if xorriso ever starts returning
nothing to the above command, this unwrap may panic. it might be nice to
do a `ok_or_else(|| bail!("xorisso command behaved unexpectedly"))?` or
similar here.
> + .replace('\'', "")
> + .trim()
> + .into();
> + break;
> + }
> + }
> + Ok(uuid)
> +}
> +
> fn get_disks() -> Result<BTreeMap<String, BTreeMap<String, String>>> {
> let unwantend_block_devs = vec![
> "ram[0-9]*",
_______________________________________________
pve-devel mailing list
pve-devel@lists.proxmox.com
https://lists.proxmox.com/cgi-bin/mailman/listinfo/pve-devel
next prev parent reply other threads:[~2024-04-30 9:41 UTC|newest]
Thread overview: 5+ messages / expand[flat|nested] mbox.gz Atom feed top
2024-04-30 8:54 Aaron Lauterer
2024-04-30 8:54 ` [pve-devel] [PATCH 2/2] assistant: use single dash for xorriso parameter Aaron Lauterer
2024-04-30 9:41 ` Stefan Sterz [this message]
2024-04-30 9:54 ` [pve-devel] [PATCH 1/2] assistant: keep prepared iso bootable on uefi with flash drives Aaron Lauterer
2024-04-30 9:53 ` Stoiko Ivanov
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=D0XCWYADW8SQ.1W8HI4SD4J9NO@proxmox.com \
--to=s.sterz@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