Send patches - preferably formatted by git format-patch - to patches at archlinux32 dot org.
summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorHugo Ankarloo <hugo@ilait.se>2021-09-20 21:46:56 +0200
committerHugo Ankarloo <hugo@ilait.se>2021-09-20 21:46:56 +0200
commit26244212cfe2d2ecbf7c791c811deb499e7a3bcf (patch)
treee4ca67d39672919f5bcf24b7c867fca072068ba7
parent915ae88947a008a21006d2572e498ed0c134350c (diff)
Fix Bug: Cannot get partuuid from loop device
File: lib/disk.py When installing on a loopback device (a.k.a loop device), function Filesystem.partuuid_to_index() crashes with a JSON parsing error. REASON 1) For loop devices, the property BlockDevice.device returns the actual image file (back-file) of the loop device instead of the /dev/X device. 2) Function Filesystem.partuuid_to_index() executes `lsblk --json` against BlockDevice.device . 3) `lsblk` fails and prints the error "not a block device" to stderr. This causes the output to not be valid JSON. 4) Code crashes when JSON parser tries to parse the output. SOLUTION - Make sure property BlockDevice.device only returns a valid block device. - Create new function BlockDevice.device_or_backfile that mimics the present behaviour of BlockDevice.device. - Use BlockDevice.device_or_backfile in function BlockDevice.__repr__(). SOLUTION REASONING I can only see one reason behind BlockDevice.device returning the back-file of a loop device, and that is to show the back-file to the user (instead of /dev/X) when printing the string representation of a BlockDevice. All other parts of the code can use the /dev/X file just fine. And IMO it makes more sense that a property named `device` only returns devices, and not normal files.
-rw-r--r--archinstall/lib/disk.py26
1 files changed, 18 insertions, 8 deletions
diff --git a/archinstall/lib/disk.py b/archinstall/lib/disk.py
index c86bf7bc..33f598bf 100644
--- a/archinstall/lib/disk.py
+++ b/archinstall/lib/disk.py
@@ -244,7 +244,7 @@ class BlockDevice:
# I'm placing the encryption password on a BlockDevice level.
def __repr__(self, *args, **kwargs):
- return f"BlockDevice({self.device}, size={self.size}GB, free_space={'+'.join(part[2] for part in self.free_space)}, bus_type={self.bus_type})"
+ return f"BlockDevice({self.device_or_backfile}, size={self.size}GB, free_space={'+'.join(part[2] for part in self.free_space)}, bus_type={self.bus_type})"
def __iter__(self):
for partition in self.partitions:
@@ -285,23 +285,33 @@ class BlockDevice:
return device['pttype']
@property
- def device(self):
+ def device_or_backfile(self):
"""
Returns the actual device-endpoint of the BlockDevice.
If it's a loop-back-device it returns the back-file,
- If it's a ATA-drive it returns the /dev/X device
- And if it's a crypto-device it returns the parent device
+ For other types it return self.device
"""
- if "type" not in self.info:
- raise DiskError(f'Could not locate backplane info for "{self.path}"')
-
if self.info['type'] == 'loop':
for drive in json.loads(SysCommand(['losetup', '--json']).decode('UTF_8'))['loopdevices']:
if not drive['name'] == self.path:
continue
return drive['back-file']
- elif self.info['type'] == 'disk':
+ else:
+ return self.device
+
+ @property
+ def device(self):
+ """
+ Returns the device file of the BlockDevice.
+ If it's a loop-back-device it returns the /dev/X device,
+ If it's a ATA-drive it returns the /dev/X device
+ And if it's a crypto-device it returns the parent device
+ """
+ if "type" not in self.info:
+ raise DiskError(f'Could not locate backplane info for "{self.path}"')
+
+ if self.info['type'] in ['disk','loop']:
return self.path
elif self.info['type'][:4] == 'raid':
# This should catch /dev/md## raid devices