Repository: archlinux/archinstall

Issue:
With efistub, efibootmgr invocation fails due to misuse of --part arg
I chose efiboot bootloader and the installation failed.
efibootmgr manual says `--part` expects the partition number.

```
['/usr/bin/efibootmgr', '--disk', '/dev/sda', '--part', '/dev/sda1', '--create', '--label', 'Arch Linux (linux)', '--loader', '/vmlinuz-linux', '--unicode', 'initrd=\\intel-ucode.img initrd=\\initramfs-linux.img root=PARTUUID=3cefb7aa-88ac-4eaa-a246-caef9e2bbbb3 rw rootfstype=ext4 ', '--verbose'] exited with abnormal exit code [37]: invalid numeric value /dev/sda1


[!] A log file has been created here: /var/log/archinstall/install.log
    Please submit this issue (and file) to https://github.com/archlinux/archinstall/issues
Traceback (most recent call last):
  File "/usr/bin/archinstall", line 8, in <module>
    sys.exit(run_as_a_module())
             ^^^^^^^^^^^^^^^^^
  File "/usr/lib/python3.11/site-packages/archinstall/__init__.py", line 291, in run_as_a_module
    importlib.import_module(mod_name)
  File "/usr/lib/python3.11/importlib/__init__.py", line 126, in import_module
    return _bootstrap._gcd_import(name[level:], package, level)
           ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
  File "<frozen importlib._bootstrap>", line 1204, in _gcd_import
  File "<frozen importlib._bootstrap>", line 1176, in _find_and_load
  File "<frozen importlib._bootstrap>", line 1147, in _find_and_load_unlocked
  File "<frozen importlib._bootstrap>", line 690, in _load_unlocked
  File "<frozen importlib._bootstrap_external>", line 940, in exec_module
  File "<frozen importlib._bootstrap>", line 241, in _call_with_frames_removed
  File "/usr/lib/python3.11/site-packages/archinstall/scripts/guided.py", line 256, in <module>
    perform_installation(archinstall.storage.get('MOUNT_POINT', Path('/mnt')))
  File "/usr/lib/python3.11/site-packages/archinstall/scripts/guided.py", line 117, in perform_installation
    with Installer(
  File "/usr/lib/python3.11/site-packages/archinstall/lib/installer.py", line 111, in __exit__
    raise exc_val
  File "/usr/lib/python3.11/site-packages/archinstall/scripts/guided.py", line 157, in perform_installation
    installation.add_bootloader(archinstall.arguments["bootloader"])
  File "/usr/lib/python3.11/site-packages/archinstall/lib/installer.py", line 1119, in add_bootloader
    self._add_efistub_bootloader(boot_partition, root_partition)
  File "/usr/lib/python3.11/site-packages/archinstall/lib/installer.py", line 1078, in _add_efistub_bootloader
    SysCommand(cmd)
  File "/usr/lib/python3.11/site-packages/archinstall/lib/general.py", line 366, in __init__
    self.create_session()
  File "/usr/lib/python3.11/site-packages/archinstall/lib/general.py", line 415, in create_session
    with SysCommandWorker(
  File "/usr/lib/python3.11/site-packages/archinstall/lib/general.py", line 199, in __exit__
    raise SysCallError(
archinstall.lib.exceptions.SysCallError: ['/usr/bin/efibootmgr', '--disk', '/dev/sda', '--part', '/dev/sda1', '--create', '--label', 'Arch Linux (linux)', '--loader', '/vmlinuz-linux', '--unicode', 'initrd=\\intel-ucode.img initrd=\\initramfs-linux.img root=PARTUUID=3cefb7aa-88ac-4eaa-a246-caef9e2bbbb3 rw rootfstype=ext4 ', '--verbose'] exited with abnormal exit code [37]: invalid numeric value /dev/sda1


[root@sysrescue ~]#
```


Discussion:
Perhaps we can change this: https://github.com/archlinux/archinstall/blob/c75ae97f007f7f7d1d8921e1bd38bcc01b6035f1/archinstall/lib/installer.py#L1087-L1088

To this:
```py
 f'--disk {parent_dev_path} ' \ 
 f'--part {str(boot_partition.safe_dev_path).lstrip(str(parent_dev_path))} ' \ 
```
I do not think that would work.

```
>>> '/dev/sda1'.lstrip('/dev/sda')
'1'
>>> '/dev/nvme0n1p1'.lstrip('/dev/nvme0n1')
'p1'
```

There is the _partn_ column in `lsblk` for partition number but it is not in `LsblkInfo` and therefore also not in `PartitionModification`.

```
lsblk -o +partn
```

It could be added to those and in `_fetch_part_info()` then `boot_partition.partn` would work.
That's a better way forward!

Resolving patch:
diff --git a/archinstall/lib/disk/device_handler.py b/archinstall/lib/disk/device_handler.py
--- a/archinstall/lib/disk/device_handler.py
+++ b/archinstall/lib/disk/device_handler.py
@@ -293,6 +293,7 @@ def format(
 
 			lsblk_info = self._fetch_part_info(part_mod.safe_dev_path)
 
+			part_mod.partn = lsblk_info.partn
 			part_mod.partuuid = lsblk_info.partuuid
 			part_mod.uuid = lsblk_info.uuid
 
@@ -371,7 +372,7 @@ def _fetch_part_info(self, path: Path) -> LsblkInfo:
 			time.sleep(attempt_nr + 1)
 			lsblk_info = get_lsblk_info(path)
 
-			if lsblk_info.partuuid and lsblk_info.uuid:
+			if lsblk_info.partn and lsblk_info.partuuid and lsblk_info.uuid:
 				break
 
 			self.partprobe(path)
@@ -380,6 +381,10 @@ def _fetch_part_info(self, path: Path) -> LsblkInfo:
 			debug(f'Unable to get partition information: {path}')
 			raise DiskError(f'Unable to get partition information: {path}')
 
+		if not lsblk_info.partn:
+			debug(f'Unable to determine new partition number: {path}\n{lsblk_info}')
+			raise DiskError(f'Unable to determine new partition number: {path}')
+
 		if not lsblk_info.partuuid:
 			debug(f'Unable to determine new partition uuid: {path}\n{lsblk_info}')
 			raise DiskError(f'Unable to determine new partition uuid: {path}')
diff --git a/archinstall/lib/disk/device_model.py b/archinstall/lib/disk/device_model.py
--- a/archinstall/lib/disk/device_model.py
+++ b/archinstall/lib/disk/device_model.py
@@ -627,6 +627,7 @@ class PartitionModification:
 
 	# only set if the device was created or exists
 	dev_path: Optional[Path] = None
+	partn: Optional[int] = None
 	partuuid: Optional[str] = None
 	uuid: Optional[str] = None
 
@@ -933,6 +934,7 @@ class LsblkInfo:
 	ptuuid: str = ''
 	rota: bool = False
 	tran: Optional[str] = None
+	partn: Optional[int] = None
 	partuuid: Optional[str] = None
 	parttype :Optional[str] = None
 	uuid: Optional[str] = None
@@ -957,6 +959,7 @@ def json(self) -> Dict[str, Any]:
 			'ptuuid': self.ptuuid,
 			'rota': self.rota,
 			'tran': self.tran,
+			'partn': self.partn,
 			'partuuid': self.partuuid,
 			'parttype' : self.parttype,
 			'uuid': self.uuid,
diff --git a/archinstall/lib/installer.py b/archinstall/lib/installer.py
--- a/archinstall/lib/installer.py
+++ b/archinstall/lib/installer.py
@@ -1085,7 +1085,7 @@ def _add_efistub_bootloader(
 
 			cmd = f'efibootmgr ' \
 				f'--disk {parent_dev_path} ' \
-				f'--part {boot_partition.safe_dev_path} ' \
+				f'--part {boot_partition.partn} ' \
 				f'--create ' \
 				f'--label "{label}" ' \
 				f'--loader {loader} ' \


Test patch: