From ffe38c879acf59da3f9d25ba866608ff6d6db64d Mon Sep 17 00:00:00 2001 From: SecondThundeR Date: Sun, 19 Sep 2021 15:49:44 +0300 Subject: general: remove all found white-spaces Also this change adds new line at the end for some scripts --- archinstall/lib/disk.py | 2 +- archinstall/lib/plugins.py | 2 +- archinstall/lib/user_interaction.py | 14 +++++++------- 3 files changed, 9 insertions(+), 9 deletions(-) (limited to 'archinstall') diff --git a/archinstall/lib/disk.py b/archinstall/lib/disk.py index 872d9bfc..5b92e1e1 100644 --- a/archinstall/lib/disk.py +++ b/archinstall/lib/disk.py @@ -1069,4 +1069,4 @@ def find_partition_by_mountpoint(block_devices, relative_mountpoint :str): for device in block_devices: for partition in block_devices[device]['partitions']: if partition.get('mountpoint', None) == relative_mountpoint: - return partition \ No newline at end of file + return partition diff --git a/archinstall/lib/plugins.py b/archinstall/lib/plugins.py index 24fbd8ee..dab5d2b0 100644 --- a/archinstall/lib/plugins.py +++ b/archinstall/lib/plugins.py @@ -98,4 +98,4 @@ def load_plugin(path :str): # -> module (not sure how to write that in type defi log(err, level=logging.ERROR) log(f"The above error was detected when initiating the plugin: {path}", fg="red", level=logging.ERROR) else: - log(f"Plugin '{path}' is missing a valid entry-point or is corrupt.", fg="yellow", level=logging.WARNING) \ No newline at end of file + log(f"Plugin '{path}' is missing a valid entry-point or is corrupt.", fg="yellow", level=logging.WARNING) diff --git a/archinstall/lib/user_interaction.py b/archinstall/lib/user_interaction.py index 6854ccfd..4ec265d4 100644 --- a/archinstall/lib/user_interaction.py +++ b/archinstall/lib/user_interaction.py @@ -575,14 +575,14 @@ def manage_new_and_existing_partitions(block_device :BlockDevice) -> dict: # log(f"Selecting which partitions to re-use on {block_device}...", fg="yellow", level=logging.INFO) # partitions = generic_multi_select(block_device.partitions.values(), "Select which partitions to re-use (the rest will be left alone): ", sort=True) # partitions_to_wipe = generic_multi_select(partitions, "Which partitions do you wish to wipe (multiple can be selected): ", sort=True) - + # mountpoints = {} # struct = { # "partitions" : [] # } # for partition in partitions: # mountpoint = input(f"Select a mountpoint (or skip) for {partition}: ").strip() - + # part_struct = {} # if mountpoint: # part_struct['mountpoint'] = mountpoint @@ -590,7 +590,7 @@ def manage_new_and_existing_partitions(block_device :BlockDevice) -> dict: # part_struct['boot'] = True # if has_uefi(): # part_struct['ESP'] = True - # elif mountpoint == '/' and + # elif mountpoint == '/' and # if partition.uuid: # part_struct['PARTUUID'] = partition.uuid # if partition in partitions_to_wipe: @@ -632,15 +632,15 @@ def manage_new_and_existing_partitions(block_device :BlockDevice) -> dict: if not task: break - + if task == 'Create a new partition': if partition_type == 'gpt': # https://www.gnu.org/software/parted/manual/html_node/mkpart.html # https://www.gnu.org/software/parted/manual/html_node/mklabel.html name = input("Enter a desired name for the partition: ").strip() - + fstype = input("Enter a desired filesystem type for the partition: ").strip() - + start = input(f"Enter the start sector (percentage or block number, default: {block_device.largest_free_space[0]}): ").strip() if not start.strip(): start = block_device.largest_free_space[0] @@ -750,7 +750,7 @@ def select_individual_blockdevice_usage(block_devices :list): for device in block_devices: layout = manage_new_and_existing_partitions(device) - + result[device.path] = layout return result -- cgit v1.2.3-54-g00ecf From d2d80113b3c6a337097b407674f67b84cc14c82a Mon Sep 17 00:00:00 2001 From: Hugo Ankarloo Date: Mon, 20 Sep 2021 19:30:07 +0200 Subject: Fix Bug: Timezone is ignored, always same as host Bug affects normal interactive usage (example/guided.py). The timezone configured in the installer is not the timezone that ends up in the new installed system. Instead, the timezone used in the host system (from where the installer is run) is the one that finally ends up being used. Reason: systemd-nspawn by default copies the host timezone into the target. And systemd-nspawn is run when keyboard-layout is changed (which is done after changing the timezone). Solution: Add option `--timezone=off` to systemd-nspawn, which hinders affecting the timezone in the target. --- archinstall/lib/systemd.py | 1 + 1 file changed, 1 insertion(+) (limited to 'archinstall') diff --git a/archinstall/lib/systemd.py b/archinstall/lib/systemd.py index 383f1f17..d297c507 100644 --- a/archinstall/lib/systemd.py +++ b/archinstall/lib/systemd.py @@ -64,6 +64,7 @@ class Boot: self.session = SysCommandWorker([ '/usr/bin/systemd-nspawn', '-D', self.instance.target, + '--timezone=off', '-b', '--machine', self.container_name ]) -- cgit v1.2.3-54-g00ecf From ffbfafb35428168366de3ced572f648c6d49dc03 Mon Sep 17 00:00:00 2001 From: Hugo Ankarloo Date: Mon, 20 Sep 2021 19:58:56 +0200 Subject: Fix Bug: config b0rked by Suggest partition layout File: lib/user_interaction.py When function manage_new_and_existing_partitions() is used, and 'Suggest partition layout' is selected, the partition info is not correctly stored in the config. Instead of: {"partitions": [{...}, {...}]} You get: {"partitions": {"partitions": [{...}, {...}], "wipe":True}} --- archinstall/lib/user_interaction.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'archinstall') diff --git a/archinstall/lib/user_interaction.py b/archinstall/lib/user_interaction.py index b017e41a..66dd3350 100644 --- a/archinstall/lib/user_interaction.py +++ b/archinstall/lib/user_interaction.py @@ -674,7 +674,7 @@ def manage_new_and_existing_partitions(block_device :BlockDevice) -> dict: if input(f"{block_device} contains queued partitions, this will remove those, are you sure? y/N: ").strip().lower() in ('', 'n'): continue - block_device_struct["partitions"] = suggest_single_disk_layout(block_device)[block_device] + block_device_struct.update( suggest_single_disk_layout(block_device)[block_device] ) elif task is None: return block_device_struct else: -- cgit v1.2.3-54-g00ecf From 915ae88947a008a21006d2572e498ed0c134350c Mon Sep 17 00:00:00 2001 From: Hugo Ankarloo Date: Mon, 20 Sep 2021 20:17:39 +0200 Subject: Fix Bug: Set filesystem crashes if no partitions File: lib/user_interaction.py When function manage_new_and_existing_partitions() is used, and no partitions are configured, and 'Set desired filesystem for a partition' is selected, the installer crashes. --- archinstall/lib/user_interaction.py | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) (limited to 'archinstall') diff --git a/archinstall/lib/user_interaction.py b/archinstall/lib/user_interaction.py index 66dd3350..ca8fb6f6 100644 --- a/archinstall/lib/user_interaction.py +++ b/archinstall/lib/user_interaction.py @@ -730,7 +730,10 @@ def manage_new_and_existing_partitions(block_device :BlockDevice) -> dict: block_device_struct["partitions"][block_device_struct["partitions"].index(partition)]['boot'] = not block_device_struct["partitions"][block_device_struct["partitions"].index(partition)].get('boot', False) elif task == "Set desired filesystem for a partition": - if (partition := generic_select(block_device_struct["partitions"], 'Select which partition to set a filesystem on: ', options_output=False)): + if not block_device_struct["partitions"]: + log("No partitions found. Create some partitions first", level=logging.WARNING, fg='yellow') + continue + elif (partition := generic_select(block_device_struct["partitions"], 'Select which partition to set a filesystem on: ', options_output=False)): if not block_device_struct["partitions"][block_device_struct["partitions"].index(partition)].get('filesystem', None): block_device_struct["partitions"][block_device_struct["partitions"].index(partition)]['filesystem'] = {} -- cgit v1.2.3-54-g00ecf From 26244212cfe2d2ecbf7c791c811deb499e7a3bcf Mon Sep 17 00:00:00 2001 From: Hugo Ankarloo Date: Mon, 20 Sep 2021 21:46:56 +0200 Subject: 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. --- archinstall/lib/disk.py | 26 ++++++++++++++++++-------- 1 file changed, 18 insertions(+), 8 deletions(-) (limited to 'archinstall') 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 -- cgit v1.2.3-54-g00ecf From 5bcbb50936690deff12a085634215c2d4f42f38c Mon Sep 17 00:00:00 2001 From: Hugo Ankarloo Date: Tue, 21 Sep 2021 00:38:20 +0200 Subject: Fix Bug: 'Suggest partition layout' crashes File: lib/user_interaction.py When function manage_new_and_existing_partitions() is used, and 'Suggest partition layout' is selected, the installer crashes. REASON Bug was introduced in commit 9e67ce3, when partition layout was changed to use device.path as keys (instead of device). It seems all necessary changes were made for this, except this one. --- archinstall/lib/user_interaction.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'archinstall') diff --git a/archinstall/lib/user_interaction.py b/archinstall/lib/user_interaction.py index be74f9b9..ba6259b1 100644 --- a/archinstall/lib/user_interaction.py +++ b/archinstall/lib/user_interaction.py @@ -674,7 +674,7 @@ def manage_new_and_existing_partitions(block_device :BlockDevice) -> dict: if input(f"{block_device} contains queued partitions, this will remove those, are you sure? y/N: ").strip().lower() in ('', 'n'): continue - block_device_struct.update( suggest_single_disk_layout(block_device)[block_device] ) + block_device_struct.update( suggest_single_disk_layout(block_device)[block_device.path] ) elif task is None: return block_device_struct else: -- cgit v1.2.3-54-g00ecf From 427492d7c9a386dbeb08561f163b9a68870f6e71 Mon Sep 17 00:00:00 2001 From: Oleksandr Zinkevych Date: Fri, 15 Oct 2021 18:03:08 +0300 Subject: Fix re_rank_mirrors --- archinstall/lib/mirrors.py | 15 +++++++++++---- 1 file changed, 11 insertions(+), 4 deletions(-) (limited to 'archinstall') diff --git a/archinstall/lib/mirrors.py b/archinstall/lib/mirrors.py index 1b62a61b..2325282f 100644 --- a/archinstall/lib/mirrors.py +++ b/archinstall/lib/mirrors.py @@ -123,10 +123,17 @@ def use_mirrors(regions: dict, destination='/etc/pacman.d/mirrorlist'): return True -def re_rank_mirrors(top=10, *positionals, **kwargs): - if SysCommand(f'/usr/bin/rankmirrors -n {top} /etc/pacman.d/mirrorlist > /etc/pacman.d/mirrorlist').exit_code == 0: - return True - return False +def re_rank_mirrors( + top: int = 10, + src: str = '/etc/pacman.d/mirrorlist', + dst: str = '/etc/pacman.d/mirrorlist', +) -> bool: + cmd = SysCommand(f"/usr/bin/rankmirrors -n {top} {src}") + if cmd.exit_code != 0: + return False + with open(dst, 'w') as f: + f.write(str(cmd)) + return True def list_mirrors(sort_order=["https", "http"]): -- cgit v1.2.3-54-g00ecf From 165d47f4bb3d79f405691a7cfb6ece55b33cd81c Mon Sep 17 00:00:00 2001 From: Oleksandr Zinkevych Date: Fri, 15 Oct 2021 18:21:35 +0300 Subject: Fix use_mirrors --- archinstall/lib/mirrors.py | 11 +++++++---- 1 file changed, 7 insertions(+), 4 deletions(-) (limited to 'archinstall') diff --git a/archinstall/lib/mirrors.py b/archinstall/lib/mirrors.py index 1b62a61b..12fa7450 100644 --- a/archinstall/lib/mirrors.py +++ b/archinstall/lib/mirrors.py @@ -1,6 +1,6 @@ import urllib.error import urllib.request -from typing import Union +from typing import Union, Mapping, Iterable from .general import * from .output import log @@ -113,10 +113,13 @@ def insert_mirrors(mirrors, *args, **kwargs): return True -def use_mirrors(regions: dict, destination='/etc/pacman.d/mirrorlist'): +def use_mirrors( + regions: Mapping[str, Iterable[str]], + destination: str ='/etc/pacman.d/mirrorlist' +) -> bool: log(f'A new package mirror-list has been created: {destination}', level=logging.INFO) - for region, mirrors in regions.items(): - with open(destination, 'w') as mirrorlist: + with open(destination, 'w') as mirrorlist: + for region, mirrors in regions.items(): for mirror in mirrors: mirrorlist.write(f'## {region}\n') mirrorlist.write(f'Server = {mirror}\n') -- cgit v1.2.3-54-g00ecf From ca25c356b687ffe9a2b63494de97607e8adc68ca Mon Sep 17 00:00:00 2001 From: Richard Neumann Date: Thu, 21 Oct 2021 22:48:52 +0200 Subject: Update type hints meminfo() returns ints. --- archinstall/lib/hardware.py | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) (limited to 'archinstall') diff --git a/archinstall/lib/hardware.py b/archinstall/lib/hardware.py index a8f87b80..e4308638 100644 --- a/archinstall/lib/hardware.py +++ b/archinstall/lib/hardware.py @@ -152,15 +152,15 @@ def product_name() -> Optional[str]: return product.read().strip() -def mem_available() -> Optional[str]: +def mem_available() -> Optional[int]: return meminfo('MemAvailable') -def mem_free() -> Optional[str]: +def mem_free() -> Optional[int]: return meminfo('MemFree') -def mem_total() -> Optional[str]: +def mem_total() -> Optional[int]: return meminfo('MemTotal') -- cgit v1.2.3-54-g00ecf From 4f6cec5069023198b047cb61e3e65fb37a93d577 Mon Sep 17 00:00:00 2001 From: Richard Neumann Date: Thu, 21 Oct 2021 22:50:49 +0200 Subject: Remove useless initialization of mem_info = {} --- archinstall/lib/hardware.py | 2 -- 1 file changed, 2 deletions(-) (limited to 'archinstall') diff --git a/archinstall/lib/hardware.py b/archinstall/lib/hardware.py index e4308638..4f8192e4 100644 --- a/archinstall/lib/hardware.py +++ b/archinstall/lib/hardware.py @@ -79,8 +79,6 @@ def meminfo(key: Optional[str] = None) -> Union[dict[str, int], int]: """Returns a dict with memory info if called with no args or the value of the given key of said dict. """ - mem_info = {} - with MEMINFO.open() as file: mem_info = { (columns := line.strip().split())[0].rstrip(':'): int(columns[1]) -- cgit v1.2.3-54-g00ecf From 63c6f39f98efcaa644d2d64c2e9468cb240a32dd Mon Sep 17 00:00:00 2001 From: Richard Neumann Date: Thu, 21 Oct 2021 22:54:00 +0200 Subject: Generalize CPU vendor detection Implement has_amd_cpu() and has_intel_cpu() as partials. --- archinstall/lib/hardware.py | 9 +++++---- 1 file changed, 5 insertions(+), 4 deletions(-) (limited to 'archinstall') diff --git a/archinstall/lib/hardware.py b/archinstall/lib/hardware.py index 4f8192e4..7172628b 100644 --- a/archinstall/lib/hardware.py +++ b/archinstall/lib/hardware.py @@ -1,4 +1,5 @@ import os +from functools import partial from pathlib import Path from typing import Iterator, Optional, Union @@ -95,11 +96,11 @@ def has_wifi() -> bool: return 'WIRELESS' in enrich_iface_types(list_interfaces().values()).values() -def has_amd_cpu() -> bool: - return any(cpu.get("vendor_id") == "AuthenticAMD" for cpu in cpuinfo()) +def has_cpu_vendor(vendor_id: str) -> bool: + return any(cpu.get("vendor_id") == vendor_id for cpu in cpuinfo()) -def has_intel_cpu() -> bool: - return any(cpu.get("vendor_id") == "GenuineIntel" for cpu in cpuinfo()) +has_amd_cpu = partial(has_cpu_vendor, "AuthenticAMD") +has_intel_cpu = partial(has_cpu_vendor, "GenuineIntel") def has_uefi() -> bool: return os.path.isdir('/sys/firmware/efi') -- cgit v1.2.3-54-g00ecf From 8eea3259245814e269e32ce69a08b81fcb2fca53 Mon Sep 17 00:00:00 2001 From: Richard Neumann Date: Thu, 21 Oct 2021 22:56:46 +0200 Subject: Improve type hint --- archinstall/lib/hardware.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'archinstall') diff --git a/archinstall/lib/hardware.py b/archinstall/lib/hardware.py index 7172628b..bbfb06a9 100644 --- a/archinstall/lib/hardware.py +++ b/archinstall/lib/hardware.py @@ -76,7 +76,7 @@ def cpuinfo() -> Iterator[dict[str, str]]: cpu[key.strip()] = value.strip() -def meminfo(key: Optional[str] = None) -> Union[dict[str, int], int]: +def meminfo(key: Optional[str] = None) -> Union[dict[str, int], Optional[int]]: """Returns a dict with memory info if called with no args or the value of the given key of said dict. """ -- cgit v1.2.3-54-g00ecf From a822b8edae2c80edc86e786e27d876b705b5c985 Mon Sep 17 00:00:00 2001 From: Oleksandr Zinkevych Date: Fri, 22 Oct 2021 14:53:18 +0300 Subject: use_mirrors: return None instead of True --- archinstall/lib/mirrors.py | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) (limited to 'archinstall') diff --git a/archinstall/lib/mirrors.py b/archinstall/lib/mirrors.py index 12fa7450..739bf1a8 100644 --- a/archinstall/lib/mirrors.py +++ b/archinstall/lib/mirrors.py @@ -116,14 +116,13 @@ def insert_mirrors(mirrors, *args, **kwargs): def use_mirrors( regions: Mapping[str, Iterable[str]], destination: str ='/etc/pacman.d/mirrorlist' -) -> bool: +) -> None: log(f'A new package mirror-list has been created: {destination}', level=logging.INFO) with open(destination, 'w') as mirrorlist: for region, mirrors in regions.items(): for mirror in mirrors: mirrorlist.write(f'## {region}\n') mirrorlist.write(f'Server = {mirror}\n') - return True def re_rank_mirrors(top=10, *positionals, **kwargs): -- cgit v1.2.3-54-g00ecf From 62f5bf4c8387f9f7591f1e1100067545b10f9b24 Mon Sep 17 00:00:00 2001 From: Anton Hvornum Date: Sat, 30 Oct 2021 20:26:54 +0200 Subject: Merging in parts of Master related to disk.py --- archinstall/lib/disk/blockdevice.py | 26 ++++++++++++++++++-------- 1 file changed, 18 insertions(+), 8 deletions(-) (limited to 'archinstall') diff --git a/archinstall/lib/disk/blockdevice.py b/archinstall/lib/disk/blockdevice.py index 57cbcfa6..d278fa2e 100644 --- a/archinstall/lib/disk/blockdevice.py +++ b/archinstall/lib/disk/blockdevice.py @@ -21,7 +21,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: @@ -62,23 +62,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 -- cgit v1.2.3-54-g00ecf From 32aa91bdded15b4bd97fd6a0c0af918fbf3affc2 Mon Sep 17 00:00:00 2001 From: Anton Hvornum Date: Sat, 30 Oct 2021 21:04:31 +0200 Subject: Adding support for passing arguments to .format() This should enable people to use custom option arguments in their config files when scripting installations or using the API. --- archinstall/lib/disk/filesystem.py | 4 ++-- archinstall/lib/disk/partition.py | 26 +++++++++++++++++++------- 2 files changed, 21 insertions(+), 9 deletions(-) (limited to 'archinstall') diff --git a/archinstall/lib/disk/filesystem.py b/archinstall/lib/disk/filesystem.py index 0328cd83..d8cc85f9 100644 --- a/archinstall/lib/disk/filesystem.py +++ b/archinstall/lib/disk/filesystem.py @@ -117,9 +117,9 @@ class Filesystem: continue break - unlocked_device.format(partition['filesystem']['format']) + unlocked_device.format(partition['filesystem']['format'], options=partition.get('options', [])) elif partition.get('format', False): - partition['device_instance'].format(partition['filesystem']['format']) + partition['device_instance'].format(partition['filesystem']['format'], options=partition.get('options', [])) if partition.get('boot', False): self.set(self.partuuid_to_index(partition['device_instance'].uuid), 'boot on') diff --git a/archinstall/lib/disk/partition.py b/archinstall/lib/disk/partition.py index 3bb2982b..40a83d6b 100644 --- a/archinstall/lib/disk/partition.py +++ b/archinstall/lib/disk/partition.py @@ -208,7 +208,7 @@ class Partition: handle = luks2(self, None, None) return handle.encrypt(self, *args, **kwargs) - def format(self, filesystem=None, path=None, log_formatting=True): + def format(self, filesystem=None, path=None, log_formatting=True, options=[]): """ Format can be given an overriding path, for instance /dev/null to test the formatting functionality and in essence the support for the given filesystem. @@ -228,33 +228,45 @@ class Partition: log(f'Formatting {path} -> {filesystem}', level=logging.INFO) if filesystem == 'btrfs': - if 'UUID:' not in (mkfs := SysCommand(f'/usr/bin/mkfs.btrfs -f {path}').decode('UTF-8')): + options = ['-f'] + options + + if 'UUID:' not in (mkfs := SysCommand(f"/usr/bin/mkfs.btrfs {' '.join(options)} {path}").decode('UTF-8')): raise DiskError(f'Could not format {path} with {filesystem} because: {mkfs}') self.filesystem = filesystem elif filesystem == 'fat32': - mkfs = SysCommand(f'/usr/bin/mkfs.vfat -F32 {path}').decode('UTF-8') + options = ['-F32'] + options + + mkfs = SysCommand(f"/usr/bin/mkfs.vfat {' '.join(options)} {path}").decode('UTF-8') if ('mkfs.fat' not in mkfs and 'mkfs.vfat' not in mkfs) or 'command not found' in mkfs: raise DiskError(f"Could not format {path} with {filesystem} because: {mkfs}") self.filesystem = filesystem elif filesystem == 'ext4': - if (handle := SysCommand(f'/usr/bin/mkfs.ext4 -F {path}')).exit_code != 0: + options = ['-F'] + options + + if (handle := SysCommand(f"/usr/bin/mkfs.ext4 {' '.join(options)} {path}")).exit_code != 0: raise DiskError(f"Could not format {path} with {filesystem} because: {handle.decode('UTF-8')}") self.filesystem = filesystem elif filesystem == 'ext2': - if (handle := SysCommand(f'/usr/bin/mkfs.ext2 -F {path}')).exit_code != 0: + options = ['-F'] + options + + if (handle := SysCommand(f"/usr/bin/mkfs.ext2 {' '.join(options)} {path}")).exit_code != 0: raise DiskError(f'Could not format {path} with {filesystem} because: {b"".join(handle)}') self.filesystem = 'ext2' elif filesystem == 'xfs': - if (handle := SysCommand(f'/usr/bin/mkfs.xfs -f {path}')).exit_code != 0: + options = ['-f'] + options + + if (handle := SysCommand(f"/usr/bin/mkfs.xfs {' '.join(options)} {path}")).exit_code != 0: raise DiskError(f"Could not format {path} with {filesystem} because: {handle.decode('UTF-8')}") self.filesystem = filesystem elif filesystem == 'f2fs': - if (handle := SysCommand(f'/usr/bin/mkfs.f2fs -f {path}')).exit_code != 0: + options = ['-f'] + options + + if (handle := SysCommand(f"/usr/bin/mkfs.f2fs {' '.join(options)} {path}")).exit_code != 0: raise DiskError(f"Could not format {path} with {filesystem} because: {handle.decode('UTF-8')}") self.filesystem = filesystem -- cgit v1.2.3-54-g00ecf From 0c4ba29978e91d3370153982395b2751a9ffa4a3 Mon Sep 17 00:00:00 2001 From: Anton Hvornum Date: Mon, 1 Nov 2021 11:57:21 +0000 Subject: Fixed general.py flake8 issues. --- archinstall/lib/general.py | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) (limited to 'archinstall') diff --git a/archinstall/lib/general.py b/archinstall/lib/general.py index 1e8fc837..4cbe9692 100644 --- a/archinstall/lib/general.py +++ b/archinstall/lib/general.py @@ -14,6 +14,7 @@ except: import select EPOLLIN = 0 EPOLLHUP = 0 + class epoll(): """ #!if windows Create a epoll() implementation that simulates the epoll() behavior. @@ -38,7 +39,7 @@ except: except OSError: return [] -from .exceptions import * +from .exceptions import RequirementError, SysCallError from .output import log from .storage import storage @@ -241,7 +242,7 @@ class SysCommandWorker: got_output = True self.peak(output) self._trace_log += output - except OSError as err: + except OSError: self.ended = time.time() break @@ -379,8 +380,7 @@ def prerequisite_check(): def reboot(): - o = b''.join(SysCommand("/usr/bin/reboot")) - + SysCommand("/usr/bin/reboot") def pid_exists(pid: int): try: -- cgit v1.2.3-54-g00ecf From b573421df294d5579116206a65ba611c788965a7 Mon Sep 17 00:00:00 2001 From: Anton Hvornum Date: Mon, 1 Nov 2021 12:03:40 +0000 Subject: Fixed flake8 issues in networking, plugins and profiles. --- archinstall/lib/networking.py | 4 ++-- archinstall/lib/plugins.py | 2 +- archinstall/lib/profiles.py | 3 ++- 3 files changed, 5 insertions(+), 4 deletions(-) (limited to 'archinstall') diff --git a/archinstall/lib/networking.py b/archinstall/lib/networking.py index ded5ebe6..0d94572a 100644 --- a/archinstall/lib/networking.py +++ b/archinstall/lib/networking.py @@ -4,7 +4,7 @@ import socket import struct from collections import OrderedDict -from .exceptions import * +from .exceptions import HardwareIncompatibilityError from .general import SysCommand from .output import log from .storage import storage @@ -30,7 +30,7 @@ def list_interfaces(skip_loopback=True): def check_mirror_reachable(): log("Testing connectivity to the Arch Linux mirrors ...", level=logging.INFO) - if (exit_code := SysCommand("pacman -Sy").exit_code) == 0: + if SysCommand("pacman -Sy").exit_code == 0: return True elif os.geteuid() != 0: log("check_mirror_reachable() uses 'pacman -Sy' which requires root.", level=logging.ERROR, fg="red") diff --git a/archinstall/lib/plugins.py b/archinstall/lib/plugins.py index dab5d2b0..027b58d5 100644 --- a/archinstall/lib/plugins.py +++ b/archinstall/lib/plugins.py @@ -65,7 +65,7 @@ def import_via_path(path :str, namespace=None): # -> module (not sure how to wri def find_nth(haystack, needle, n): start = haystack.find(needle) while start >= 0 and n > 1: - start = haystack.find(needle, start+len(needle)) + start = haystack.find(needle, start + len(needle)) n -= 1 return start diff --git a/archinstall/lib/profiles.py b/archinstall/lib/profiles.py index ebb08990..cd86ba1f 100644 --- a/archinstall/lib/profiles.py +++ b/archinstall/lib/profiles.py @@ -1,6 +1,7 @@ import hashlib import importlib.util import json +import os import re import ssl import sys @@ -10,7 +11,7 @@ import urllib.request from typing import Optional from .general import multisplit -from .networking import * +from .networking import list_interfaces from .storage import storage -- cgit v1.2.3-54-g00ecf From a868bc095de3d83213c3b246d569a808bfd85150 Mon Sep 17 00:00:00 2001 From: Didr Date: Mon, 1 Nov 2021 13:05:09 +0100 Subject: Add import for all_disks --- archinstall/lib/disk/blockdevice.py | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) (limited to 'archinstall') diff --git a/archinstall/lib/disk/blockdevice.py b/archinstall/lib/disk/blockdevice.py index d278fa2e..0b0bb37c 100644 --- a/archinstall/lib/disk/blockdevice.py +++ b/archinstall/lib/disk/blockdevice.py @@ -7,6 +7,7 @@ from ..general import SysCommand class BlockDevice: def __init__(self, path, info=None): if not info: + from .helpers import all_disks # If we don't give any information, we need to auto-fill it. # Otherwise any subsequent usage will break. info = all_disks()[path].info @@ -220,4 +221,4 @@ class BlockDevice: def get_partition(self, uuid): for partition in self: if partition.uuid == uuid: - return partition \ No newline at end of file + return partition -- cgit v1.2.3-54-g00ecf From 675db53f1d25f24fe1387cb87ce1a54af94ee399 Mon Sep 17 00:00:00 2001 From: TheEvilSkeleton Date: Tue, 2 Nov 2021 12:01:07 -0400 Subject: Fix typos --- archinstall/lib/storage.py | 2 +- examples/guided.py | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) (limited to 'archinstall') diff --git a/archinstall/lib/storage.py b/archinstall/lib/storage.py index 67f8e716..ae330382 100644 --- a/archinstall/lib/storage.py +++ b/archinstall/lib/storage.py @@ -4,7 +4,7 @@ import os # 1. In the git repository, where ./profiles/ exist # 2. When executing from a remote directory, but targeted a script that starts from the git repository # 3. When executing as a python -m archinstall module where profiles exist one step back for library reasons. -# (4. Added the ~/.config directory as a additional option for future reasons) +# (4. Added the ~/.config directory as an additional option for future reasons) # # And Keeping this in dict ensures that variables are shared across imports. storage = { diff --git a/examples/guided.py b/examples/guided.py index 60539a0b..c5fe9c91 100644 --- a/examples/guided.py +++ b/examples/guided.py @@ -146,7 +146,7 @@ def ask_user_questions(): # Ask for additional users (super-user if root pw was not set) if not archinstall.arguments.get('!root-password', None) and not archinstall.arguments.get('superusers', None): archinstall.arguments['superusers'] = archinstall.ask_for_superuser_account('Create a required super-user with sudo privileges: ', forced=True) - users, superusers = archinstall.ask_for_additional_users('Enter a username to create a additional user (leave blank to skip & continue): ') + users, superusers = archinstall.ask_for_additional_users('Enter a username to create an additional user (leave blank to skip & continue): ') archinstall.arguments['users'] = users archinstall.arguments['superusers'] = {**archinstall.arguments['superusers'], **superusers} -- cgit v1.2.3-54-g00ecf From 2fcd8198b28744bad471b11d287a39ead267af67 Mon Sep 17 00:00:00 2001 From: Anton Hvornum Date: Fri, 5 Nov 2021 16:27:01 +0100 Subject: Cleaned up all flake8 issues/warnings. Did some code cleaning as well, mostly how we called things in guided.py but also some SysCommand calls --- .flake8 | 2 +- archinstall/lib/disk/__init__.py | 2 +- archinstall/lib/disk/blockdevice.py | 14 ++++++++------ archinstall/lib/disk/btrfs.py | 13 +++++++------ archinstall/lib/disk/filesystem.py | 12 ++++++------ archinstall/lib/disk/helpers.py | 5 +++-- archinstall/lib/disk/partition.py | 11 +++++++---- archinstall/lib/disk/user_guides.py | 5 +++-- archinstall/lib/disk/validators.py | 2 +- archinstall/lib/general.py | 2 +- archinstall/lib/hardware.py | 4 ++++ archinstall/lib/installer.py | 35 +++++++++++++++++++++-------------- archinstall/lib/luks.py | 9 +++++++-- archinstall/lib/mirrors.py | 14 +++++++------- archinstall/lib/packages.py | 2 +- archinstall/lib/profiles.py | 1 + archinstall/lib/services.py | 3 ++- archinstall/lib/user_interaction.py | 32 +++++++++++++++----------------- examples/guided.py | 26 ++++++-------------------- 19 files changed, 102 insertions(+), 92 deletions(-) (limited to 'archinstall') diff --git a/.flake8 b/.flake8 index 7226c609..673661eb 100644 --- a/.flake8 +++ b/.flake8 @@ -1,7 +1,7 @@ [flake8] count = True # Several of the following could be autofixed or improved by running the code through psf/black -ignore = E126,E128,E203,E231,E261,E302,E402,E722,F541,W191 +ignore = E126,E128,E203,E231,E261,E302,E402,E722,F541,W191,W292,W293 max-complexity = 40 max-line-length = 236 show-source = True diff --git a/archinstall/lib/disk/__init__.py b/archinstall/lib/disk/__init__.py index 352d04b9..bb6eb815 100644 --- a/archinstall/lib/disk/__init__.py +++ b/archinstall/lib/disk/__init__.py @@ -4,4 +4,4 @@ from .blockdevice import BlockDevice from .filesystem import Filesystem, MBR, GPT from .partition import * from .user_guides import * -from .validators import * \ No newline at end of file +from .validators import * diff --git a/archinstall/lib/disk/blockdevice.py b/archinstall/lib/disk/blockdevice.py index d278fa2e..8f5c0a85 100644 --- a/archinstall/lib/disk/blockdevice.py +++ b/archinstall/lib/disk/blockdevice.py @@ -1,6 +1,8 @@ import os import json import logging +from .exceptions import DiskError +from .helpers import all_disks from ..output import log from ..general import SysCommand @@ -57,7 +59,7 @@ class BlockDevice: @property def partition_type(self): output = json.loads(SysCommand(f"lsblk --json -o+PTTYPE {self.path}").decode('UTF-8')) - + for device in output['blockdevices']: return device['pttype'] @@ -164,21 +166,21 @@ class BlockDevice: @property def size(self): output = json.loads(SysCommand(f"lsblk --json -o+SIZE {self.path}").decode('UTF-8')) - + for device in output['blockdevices']: return self.convert_size_to_gb(device['size']) @property def bus_type(self): output = json.loads(SysCommand(f"lsblk --json -o+ROTA,TRAN {self.path}").decode('UTF-8')) - + for device in output['blockdevices']: return device['tran'] - + @property def spinning(self): output = json.loads(SysCommand(f"lsblk --json -o+ROTA,TRAN {self.path}").decode('UTF-8')) - + for device in output['blockdevices']: return device['rota'] is True @@ -220,4 +222,4 @@ class BlockDevice: def get_partition(self, uuid): for partition in self: if partition.uuid == uuid: - return partition \ No newline at end of file + return partition diff --git a/archinstall/lib/disk/btrfs.py b/archinstall/lib/disk/btrfs.py index 6fafab34..7ae4f6a6 100644 --- a/archinstall/lib/disk/btrfs.py +++ b/archinstall/lib/disk/btrfs.py @@ -1,4 +1,5 @@ -import pathlib, glob +import pathlib +import glob import logging from typing import Union from .helpers import get_mount_info @@ -27,9 +28,9 @@ def mount_subvolume(installation, subvolume_location :Union[pathlib.Path, str], if not target.exists(): target.mkdir(parents=True) - if glob.glob(str(target/'*')) and force is False: + if glob.glob(str(target / '*')) and force is False: raise DiskError(f"Cannot mount subvolume to {target} because it contains data (non-empty folder target)") - + log(f"Mounting {target} as a subvolume", level=logging.INFO) # Mount the logical volume to the physical structure mount_information, mountpoint_device_real_path = get_mount_info(target, traverse=True, return_real_path=True) @@ -46,7 +47,7 @@ def create_subvolume(installation, subvolume_location :Union[pathlib.Path, str]) @installation: archinstall.Installer instance @subvolume_location: a localized string or path inside the installation / or /boot for instance without specifying /mnt/boot """ - + installation_mountpoint = installation.target if type(installation_mountpoint) == str: installation_mountpoint = pathlib.Path(installation_mountpoint) @@ -61,7 +62,7 @@ def create_subvolume(installation, subvolume_location :Union[pathlib.Path, str]) if not target.parent.exists(): target.parent.mkdir(parents=True) - if glob.glob(str(target/'*')) and force is False: + if glob.glob(str(target / '*')): raise DiskError(f"Cannot create subvolume at {target} because it contains data (non-empty folder target)") # Remove the target if it exists @@ -70,4 +71,4 @@ def create_subvolume(installation, subvolume_location :Union[pathlib.Path, str]) log(f"Creating a subvolume on {target}", level=logging.INFO) if (cmd := SysCommand(f"btrfs subvolume create {target}")).exit_code != 0: - raise DiskError(f"Could not create a subvolume at {target}: {cmd}") \ No newline at end of file + raise DiskError(f"Could not create a subvolume at {target}: {cmd}") diff --git a/archinstall/lib/disk/filesystem.py b/archinstall/lib/disk/filesystem.py index d8cc85f9..69593d08 100644 --- a/archinstall/lib/disk/filesystem.py +++ b/archinstall/lib/disk/filesystem.py @@ -1,8 +1,9 @@ import time import logging import json +from .exceptions import DiskError from .partition import Partition -from .blockdevice import BlockDevice +from .validators import valid_fs_type from ..general import SysCommand from ..output import log from ..storage import storage @@ -55,7 +56,7 @@ class Filesystem: def partuuid_to_index(self, uuid): output = json.loads(SysCommand(f"lsblk --json -o+PARTUUID {self.blockdevice.device}").decode('UTF-8')) - + for device in output['blockdevices']: for index, partition in enumerate(device['children']): if partition['partuuid'].lower() == uuid: @@ -101,7 +102,7 @@ class Filesystem: partition['password'] = get_password(f"Enter a encryption password for {partition['device_instance']}") partition['device_instance'].encrypt(password=partition['password']) - with luks2(partition['device_instance'], storage.get('ENC_IDENTIFIER', 'ai')+'loop', partition['password']) as unlocked_device: + with luks2(partition['device_instance'], storage.get('ENC_IDENTIFIER', 'ai') + 'loop', partition['password']) as unlocked_device: if not partition.get('format'): if storage['arguments'] == 'silent': raise ValueError(f"Missing fs-type to format on newly created encrypted partition {partition['device_instance']}") @@ -113,7 +114,7 @@ class Filesystem: while True: partition['filesystem']['format'] = input(f"Enter a valid fs-type for newly encrypted partition {partition['filesystem']['format']}: ").strip() if not partition['filesystem']['format'] or valid_fs_type(partition['filesystem']['format']) is False: - pint("You need to enter a valid fs-type in order to continue. See `man parted` for valid fs-type's.") + print("You need to enter a valid fs-type in order to continue. See `man parted` for valid fs-type's.") continue break @@ -170,7 +171,6 @@ class Filesystem: raise DiskError(f"New partition never showed up after adding new partition on {self} (timeout 10 seconds).") time.sleep(0.025) - # Todo: Find a better way to detect if the new UUID of the partition has showed up. # But this will address (among other issues) time.sleep(float(storage['arguments'].get('disk-sleep', 2.0))) # Let the kernel catch up with quick block devices (nvme for instance) @@ -190,4 +190,4 @@ class Filesystem: SysCommand(f'bash -c "umount {device}?"') except: pass - return self.raw_parted(f'{device} mklabel {disk_label}').exit_code == 0 \ No newline at end of file + return self.raw_parted(f'{device} mklabel {disk_label}').exit_code == 0 diff --git a/archinstall/lib/disk/helpers.py b/archinstall/lib/disk/helpers.py index 341b732f..8e044ce3 100644 --- a/archinstall/lib/disk/helpers.py +++ b/archinstall/lib/disk/helpers.py @@ -1,10 +1,11 @@ import re +import os import json import logging import pathlib from typing import Union from .blockdevice import BlockDevice -from ..exceptions import SysCallError +from ..exceptions import SysCallError, DiskError from ..general import SysCommand from ..output import log @@ -199,4 +200,4 @@ def find_partition_by_mountpoint(block_devices, relative_mountpoint :str): for device in block_devices: for partition in block_devices[device]['partitions']: if partition.get('mountpoint', None) == relative_mountpoint: - return partition \ No newline at end of file + return partition diff --git a/archinstall/lib/disk/partition.py b/archinstall/lib/disk/partition.py index 40a83d6b..afe46db3 100644 --- a/archinstall/lib/disk/partition.py +++ b/archinstall/lib/disk/partition.py @@ -4,9 +4,12 @@ import time import logging import json import os +import hashlib from typing import Optional from .blockdevice import BlockDevice +from .exceptions import DiskError, SysCallError, UnknownFilesystemFormat from .helpers import get_mount_info, get_filesystem_type +from .storage import storage from ..output import log from ..general import SysCommand @@ -82,14 +85,14 @@ class Partition: @property def sector_size(self): output = json.loads(SysCommand(f"lsblk --json -o+LOG-SEC {self.path}").decode('UTF-8')) - + for device in output['blockdevices']: return device.get('log-sec', None) @property def start(self): output = json.loads(SysCommand(f"sfdisk --json {self.block_device.path}").decode('UTF-8')) - + for partition in output.get('partitiontable', {}).get('partitions', []): if partition['node'] == self.path: return partition['start']# * self.sector_size @@ -173,7 +176,7 @@ class Partition: from .luks import luks2 try: - with luks2(self, storage.get('ENC_IDENTIFIER', 'ai')+'loop', password, auto_unmount=True) as unlocked_device: + with luks2(self, storage.get('ENC_IDENTIFIER', 'ai') + 'loop', password, auto_unmount=True) as unlocked_device: return unlocked_device.filesystem except SysCallError: return None @@ -346,4 +349,4 @@ class Partition: pass # We supported it, but /dev/null is not formatable as expected so the mkfs call exited with an error code except UnknownFilesystemFormat as err: raise err - return True \ No newline at end of file + return True diff --git a/archinstall/lib/disk/user_guides.py b/archinstall/lib/disk/user_guides.py index 6f8a1edb..e235dfc9 100644 --- a/archinstall/lib/disk/user_guides.py +++ b/archinstall/lib/disk/user_guides.py @@ -1,4 +1,5 @@ import logging +from .helpers import sort_block_devices_based_on_performance, select_largest_device, select_disk_larger_than_or_close_to from ..output import log def suggest_single_disk_layout(block_device, default_filesystem=None): @@ -55,7 +56,7 @@ def suggest_single_disk_layout(block_device, default_filesystem=None): } } else: - pass #... implement a guided setup + pass # ... implement a guided setup elif block_device.size >= MIN_SIZE_TO_ALLOW_HOME_PART: # If we don't want to use subvolumes, @@ -146,4 +147,4 @@ def suggest_multi_disk_layout(block_devices, default_filesystem=None): } }) - return layout \ No newline at end of file + return layout diff --git a/archinstall/lib/disk/validators.py b/archinstall/lib/disk/validators.py index 0c9f5a74..e0ab6a86 100644 --- a/archinstall/lib/disk/validators.py +++ b/archinstall/lib/disk/validators.py @@ -39,4 +39,4 @@ def valid_fs_type(fstype :str) -> bool: "reiserfs", "udf", # "ufs", not included in `man parted` "xfs", # `man parted` allows this - ] \ No newline at end of file + ] diff --git a/archinstall/lib/general.py b/archinstall/lib/general.py index 4cbe9692..887a60d3 100644 --- a/archinstall/lib/general.py +++ b/archinstall/lib/general.py @@ -14,7 +14,7 @@ except: import select EPOLLIN = 0 EPOLLHUP = 0 - + class epoll(): """ #!if windows Create a epoll() implementation that simulates the epoll() behavior. diff --git a/archinstall/lib/hardware.py b/archinstall/lib/hardware.py index bbfb06a9..cf99a530 100644 --- a/archinstall/lib/hardware.py +++ b/archinstall/lib/hardware.py @@ -99,9 +99,13 @@ def has_wifi() -> bool: def has_cpu_vendor(vendor_id: str) -> bool: return any(cpu.get("vendor_id") == vendor_id for cpu in cpuinfo()) + has_amd_cpu = partial(has_cpu_vendor, "AuthenticAMD") + + has_intel_cpu = partial(has_cpu_vendor, "GenuineIntel") + def has_uefi() -> bool: return os.path.isdir('/sys/firmware/efi') diff --git a/archinstall/lib/installer.py b/archinstall/lib/installer.py index 0bdddb2e..47a26d6d 100644 --- a/archinstall/lib/installer.py +++ b/archinstall/lib/installer.py @@ -1,14 +1,23 @@ import time -from .disk import * -from .hardware import * +import logging +import os +import shutil +import pathlib +import subprocess +import glob +from .disk import get_partitions_in_use, Partition, find_partition +from .general import SysCommand +from .hardware import has_uefi, is_vm, cpu_vendor from .locale_helpers import verify_keyboard_layout, verify_x11_keyboard_layout from .disk.helpers import get_mount_info -from .mirrors import * +from .mirrors import use_mirrors from .plugins import plugins from .storage import storage -from .user_interaction import * +# from .user_interaction import * +from .output import log +from .profiles import Profile from .disk.btrfs import create_subvolume, mount_subvolume -from .exceptions import DiskError, ServiceException +from .exceptions import DiskError, ServiceException, RequirementError, HardwareIncompatibilityError # Any package that the Installer() is responsible for (optional and the default ones) __packages__ = ["base", "base-devel", "linux-firmware", "linux", "linux-lts", "linux-zen", "linux-hardened"] @@ -139,7 +148,7 @@ class Installer: for mountpoint in sorted(mountpoints.keys()): if mountpoints[mountpoint]['encrypted']: - loopdev = storage.get('ENC_IDENTIFIER', 'ai')+'loop' + loopdev = storage.get('ENC_IDENTIFIER', 'ai') + 'loop' password = mountpoints[mountpoint]['password'] with luks2(mountpoints[mountpoint]['device_instance'], loopdev, password, auto_unmount=False) as unlocked_device: unlocked_device.mount(f"{self.target}{mountpoint}") @@ -198,7 +207,7 @@ class Installer: self.log(f"Updating {self.target}/etc/fstab", level=logging.INFO) with open(f"{self.target}/etc/fstab", 'a') as fstab_fh: - fstab_fh.write(SysCommand(f'/usr/bin/genfstab {flags} {self.target}').decode()) + fstab_fh.write((fstab := SysCommand(f'/usr/bin/genfstab {flags} {self.target}')).decode()) if not os.path.isfile(f'{self.target}/etc/fstab'): raise RequirementError(f'Could not generate fstab, strapping in packages most likely failed (disk out of space?)\n{fstab}') @@ -554,7 +563,7 @@ class Installer: self.helper_flags['bootloader'] = True return True else: - boot_partition = filesystem.find_partition(mountpoint=f"{self.target}/boot") + boot_partition = find_partition(mountpoint=f"{self.target}/boot") SysCommand(f'/usr/bin/arch-chroot {self.target} grub-install --target=i386-pc --recheck {boot_partition.path}') SysCommand(f'/usr/bin/arch-chroot {self.target} grub-mkconfig -o /boot/grub/grub.cfg') self.helper_flags['bootloader'] = True @@ -595,14 +604,14 @@ class Installer: if not handled_by_plugin: self.log(f'Creating user {user}', level=logging.INFO) - o = b''.join(SysCommand(f'/usr/bin/arch-chroot {self.target} useradd -m -G wheel {user}')) + SysCommand(f'/usr/bin/arch-chroot {self.target} useradd -m -G wheel {user}') if password: self.user_set_pw(user, password) if groups: for group in groups: - o = b''.join(SysCommand(f'/usr/bin/arch-chroot {self.target} gpasswd -a {user} {group}')) + SysCommand(f'/usr/bin/arch-chroot {self.target} gpasswd -a {user} {group}') if sudo and self.enable_sudo(user): self.helper_flags['user'] = True @@ -614,14 +623,12 @@ class Installer: # This means the root account isn't locked/disabled with * in /etc/passwd self.helper_flags['user'] = True - o = b''.join(SysCommand(f"/usr/bin/arch-chroot {self.target} sh -c \"echo '{user}:{password}' | chpasswd\"")) - pass + SysCommand(f"/usr/bin/arch-chroot {self.target} sh -c \"echo '{user}:{password}' | chpasswd\"") def user_set_shell(self, user, shell): self.log(f'Setting shell for {user} to {shell}', level=logging.INFO) - o = b''.join(SysCommand(f"/usr/bin/arch-chroot {self.target} sh -c \"chsh -s {shell} {user}\"")) - pass + SysCommand(f"/usr/bin/arch-chroot {self.target} sh -c \"chsh -s {shell} {user}\"") def set_keyboard_language(self, language: str) -> bool: if len(language.strip()): diff --git a/archinstall/lib/luks.py b/archinstall/lib/luks.py index 781bed43..d10058ef 100644 --- a/archinstall/lib/luks.py +++ b/archinstall/lib/luks.py @@ -1,9 +1,14 @@ +import json +import logging +import os import pathlib +import shlex +import time from .disk import Partition -from .general import * +from .general import SysCommand from .output import log - +from .exceptions import SysCallError, DiskError class luks2: def __init__(self, partition, mountpoint, password, key_file=None, auto_unmount=False, *args, **kwargs): diff --git a/archinstall/lib/mirrors.py b/archinstall/lib/mirrors.py index ed34b5d5..5fad6cb6 100644 --- a/archinstall/lib/mirrors.py +++ b/archinstall/lib/mirrors.py @@ -1,8 +1,9 @@ +import logging import urllib.error import urllib.request from typing import Union, Mapping, Iterable -from .general import * +from .general import SysCommand from .output import log def sort_mirrorlist(raw_data :bytes, sort_order=["https", "http"]) -> bytes: @@ -26,7 +27,7 @@ def sort_mirrorlist(raw_data :bytes, sort_order=["https", "http"]) -> bytes: """ comments_and_whitespaces = b"" - categories = {key: [] for key in sort_order+["Unknown"]} + categories = {key: [] for key in sort_order + ["Unknown"]} for line in raw_data.split(b"\n"): if line[0:2] in (b'##', b''): comments_and_whitespaces += line + b'\n' @@ -35,16 +36,15 @@ def sort_mirrorlist(raw_data :bytes, sort_order=["https", "http"]) -> bytes: opening, url = opening.strip(), url.strip() if (category := url.split(b'://',1)[0].decode('UTF-8')) in categories: categories[category].append(comments_and_whitespaces) - categories[category].append(opening+b' = '+url+b'\n') + categories[category].append(opening + b' = ' + url + b'\n') else: categories["Unknown"].append(comments_and_whitespaces) - categories["Unknown"].append(opening+b' = '+url+b'\n') + categories["Unknown"].append(opening + b' = ' + url + b'\n') comments_and_whitespaces = b"" - new_raw_data = b'' - for category in sort_order+["Unknown"]: + for category in sort_order + ["Unknown"]: for line in categories[category]: new_raw_data += line @@ -115,7 +115,7 @@ def insert_mirrors(mirrors, *args, **kwargs): def use_mirrors( regions: Mapping[str, Iterable[str]], - destination: str ='/etc/pacman.d/mirrorlist' + destination: str = '/etc/pacman.d/mirrorlist' ) -> None: log(f'A new package mirror-list has been created: {destination}', level=logging.INFO) with open(destination, 'w') as mirrorlist: diff --git a/archinstall/lib/packages.py b/archinstall/lib/packages.py index 0178d257..ffc44cbe 100644 --- a/archinstall/lib/packages.py +++ b/archinstall/lib/packages.py @@ -4,7 +4,7 @@ import urllib.error import urllib.parse import urllib.request -from .exceptions import * +from .exceptions import RequirementError BASE_URL = 'https://archlinux.org/packages/search/json/?name={package}' BASE_GROUP_URL = 'https://archlinux.org/groups/x86_64/{group}/' diff --git a/archinstall/lib/profiles.py b/archinstall/lib/profiles.py index cd86ba1f..7d5373c5 100644 --- a/archinstall/lib/profiles.py +++ b/archinstall/lib/profiles.py @@ -13,6 +13,7 @@ from typing import Optional from .general import multisplit from .networking import list_interfaces from .storage import storage +from .exceptions import ProfileNotFound def grab_url_data(path): diff --git a/archinstall/lib/services.py b/archinstall/lib/services.py index 6f8f2a87..d295bdbb 100644 --- a/archinstall/lib/services.py +++ b/archinstall/lib/services.py @@ -1,4 +1,5 @@ -from .general import * +import os +from .general import SysCommand def service_state(service_name: str): diff --git a/archinstall/lib/user_interaction.py b/archinstall/lib/user_interaction.py index ba6259b1..6b142288 100644 --- a/archinstall/lib/user_interaction.py +++ b/archinstall/lib/user_interaction.py @@ -10,14 +10,13 @@ import sys import time from .disk import BlockDevice, valid_fs_type, find_partition_by_mountpoint, suggest_single_disk_layout, suggest_multi_disk_layout, valid_parted_position -from .exceptions import * -from .general import SysCommand +from .exceptions import RequirementError, UserError, DiskError from .hardware import AVAILABLE_GFX_DRIVERS, has_uefi, has_amd_graphics, has_intel_graphics, has_nvidia_graphics from .locale_helpers import list_keyboard_languages, verify_keyboard_layout, search_keyboard_layout from .networking import list_interfaces from .output import log from .profiles import Profile, list_profiles -from .storage import * +from .storage import storage # TODO: Some inconsistencies between the selection processes. # Some return the keys from the options, some the values? @@ -201,11 +200,11 @@ def select_encrypted_partitions(block_devices :dict, password :str) -> dict: return block_devices # TODO: Next version perhaps we can support multiple encrypted partitions - #options = [] - #for partition in block_devices.values(): - # options.append({key: val for key, val in partition.items() if val}) + # options = [] + # for partition in block_devices.values(): + # options.append({key: val for key, val in partition.items() if val}) - #print(generic_multi_select(options, f"Choose which partitions to encrypt (leave blank when done): ")) + # print(generic_multi_select(options, f"Choose which partitions to encrypt (leave blank when done): ")) class MiniCurses: def __init__(self, width, height): @@ -567,10 +566,10 @@ def get_default_partition_layout(block_devices): # TODO: Implement sane generic layout for 2+ drives def manage_new_and_existing_partitions(block_device :BlockDevice) -> dict: - if has_uefi(): - partition_type = 'gpt' - else: - partition_type = 'msdos' + # if has_uefi(): + # partition_type = 'gpt' + # else: + # partition_type = 'msdos' # log(f"Selecting which partitions to re-use on {block_device}...", fg="yellow", level=logging.INFO) # partitions = generic_multi_select(block_device.partitions.values(), "Select which partitions to re-use (the rest will be left alone): ", sort=True) @@ -600,7 +599,6 @@ def manage_new_and_existing_partitions(block_device :BlockDevice) -> dict: # return struct - mountpoints = {} block_device_struct = { "partitions" : [partition.__dump__() for partition in block_device.partitions.values()] } @@ -634,10 +632,10 @@ def manage_new_and_existing_partitions(block_device :BlockDevice) -> dict: break if task == 'Create a new partition': - if partition_type == 'gpt': - # https://www.gnu.org/software/parted/manual/html_node/mkpart.html - # https://www.gnu.org/software/parted/manual/html_node/mklabel.html - name = input("Enter a desired name for the partition: ").strip() + # if partition_type == 'gpt': + # # https://www.gnu.org/software/parted/manual/html_node/mkpart.html + # # https://www.gnu.org/software/parted/manual/html_node/mklabel.html + # name = input("Enter a desired name for the partition: ").strip() fstype = input("Enter a desired filesystem type for the partition: ").strip() @@ -674,7 +672,7 @@ def manage_new_and_existing_partitions(block_device :BlockDevice) -> dict: if input(f"{block_device} contains queued partitions, this will remove those, are you sure? y/N: ").strip().lower() in ('', 'n'): continue - block_device_struct.update( suggest_single_disk_layout(block_device)[block_device.path] ) + block_device_struct.update(suggest_single_disk_layout(block_device)[block_device.path]) elif task is None: return block_device_struct else: diff --git a/examples/guided.py b/examples/guided.py index 60539a0b..50fb3a43 100644 --- a/examples/guided.py +++ b/examples/guided.py @@ -5,10 +5,6 @@ import pathlib import time import archinstall -from archinstall.lib.general import run_custom_user_commands -from archinstall.lib.hardware import * -from archinstall.lib.networking import check_mirror_reachable -from archinstall.lib.profiles import Profile, is_desktop_profile if archinstall.arguments.get('help'): print("See `man archinstall` for help.") @@ -51,7 +47,7 @@ def load_config(): if archinstall.arguments.get('sys-encoding', None) is not None: archinstall.arguments['sys-encoding'] = archinstall.arguments.get('sys-encoding', 'utf-8') if archinstall.arguments.get('gfx_driver', None) is not None: - archinstall.storage['gfx_driver_packages'] = AVAILABLE_GFX_DRIVERS.get(archinstall.arguments.get('gfx_driver', None), None) + archinstall.storage['gfx_driver_packages'] = archinstall.hardware.AVAILABLE_GFX_DRIVERS.get(archinstall.arguments.get('gfx_driver', None), None) if archinstall.arguments.get('servers', None) is not None: archinstall.storage['_selected_servers'] = archinstall.arguments.get('servers', None) if archinstall.arguments.get('disk_layouts', None) is not None: @@ -81,13 +77,11 @@ def ask_user_questions(): except archinstall.RequirementError as err: archinstall.log(err, fg="red") - # Before continuing, set the preferred keyboard layout/language in the current terminal. # This will just help the user with the next following questions. if len(archinstall.arguments['keyboard-layout']): archinstall.set_keyboard_language(archinstall.arguments['keyboard-layout']) - # Set which region to download packages from during the installation if not archinstall.arguments.get('mirror-region', None): while True: @@ -132,17 +126,14 @@ def ask_user_questions(): if not archinstall.arguments.get("bootloader", None): archinstall.arguments["bootloader"] = archinstall.ask_for_bootloader() - # Get the hostname for the machine if not archinstall.arguments.get('hostname', None): archinstall.arguments['hostname'] = input('Desired hostname for the installation: ').strip(' ') - # Ask for a root password (optional, but triggers requirement for super-user if skipped) if not archinstall.arguments.get('!root-password', None): archinstall.arguments['!root-password'] = archinstall.get_password(prompt='Enter root password (leave blank to disable disabled & create superuser): ') - # Ask for additional users (super-user if root pw was not set) if not archinstall.arguments.get('!root-password', None) and not archinstall.arguments.get('superusers', None): archinstall.arguments['superusers'] = archinstall.ask_for_superuser_account('Create a required super-user with sudo privileges: ', forced=True) @@ -150,12 +141,10 @@ def ask_user_questions(): archinstall.arguments['users'] = users archinstall.arguments['superusers'] = {**archinstall.arguments['superusers'], **superusers} - # Ask for archinstall-specific profiles (such as desktop environments etc) if not archinstall.arguments.get('profile', None): archinstall.arguments['profile'] = archinstall.select_profile() - # Check the potentially selected profiles preparations to get early checks if some additional questions are needed. if archinstall.arguments['profile'] and archinstall.arguments['profile'].has_prep_function(): with archinstall.arguments['profile'].load_instructions(namespace=f"{archinstall.arguments['profile'].namespace}.py") as imported: @@ -163,19 +152,16 @@ def ask_user_questions(): archinstall.log(' * Profile\'s preparation requirements was not fulfilled.', fg='red') exit(1) - # Ask about audio server selection if one is not already set if not archinstall.arguments.get('audio', None): # The argument to ask_for_audio_selection lets the library know if it's a desktop profile - archinstall.arguments['audio'] = archinstall.ask_for_audio_selection(is_desktop_profile(archinstall.arguments['profile'])) - + archinstall.arguments['audio'] = archinstall.ask_for_audio_selection(archinstall.profiles.is_desktop_profile(archinstall.arguments['profile'])) # Ask for preferred kernel: if not archinstall.arguments.get("kernels", None): kernels = ["linux", "linux-lts", "linux-zen", "linux-hardened"] archinstall.arguments['kernels'] = archinstall.select_kernel(kernels) - # Additional packages (with some light weight error handling for invalid package names) print("Only packages such as base, base-devel, linux, linux-firmware, efibootmgr and optional profile packages are installed.") print("If you desire a web browser, such as firefox or chromium, you may specify it in the following prompt.") @@ -246,7 +232,7 @@ def perform_filesystem_operations(): Once that's done, we'll hand over to perform_installation() """ mode = archinstall.GPT - if has_uefi() is False: + if archinstall.has_uefi() is False: mode = archinstall.MBR for drive in archinstall.arguments['harddrives']: @@ -279,7 +265,7 @@ def perform_installation(mountpoint): installation.set_hostname(archinstall.arguments['hostname']) if archinstall.arguments['mirror-region'].get("mirrors", None) is not None: installation.set_mirrors(archinstall.arguments['mirror-region']) # Set the mirrors in the installation medium - if archinstall.arguments["bootloader"] == "grub-install" and has_uefi(): + if archinstall.arguments["bootloader"] == "grub-install" and archinstall.has_uefi(): installation.add_additional_packages("grub") installation.add_bootloader(archinstall.arguments["bootloader"]) @@ -346,7 +332,7 @@ def perform_installation(mountpoint): # If the user provided custom commands to be run post-installation, execute them now. if archinstall.arguments.get('custom-commands', None): - run_custom_user_commands(archinstall.arguments['custom-commands'], installation) + archinstall.run_custom_user_commands(archinstall.arguments['custom-commands'], installation) installation.log("For post-installation tips, see https://wiki.archlinux.org/index.php/Installation_guide#Post-installation", fg="yellow") if not archinstall.arguments.get('silent'): @@ -361,7 +347,7 @@ def perform_installation(mountpoint): archinstall.log(f"Disk states after installing: {archinstall.disk_layouts()}", level=logging.DEBUG) -if not check_mirror_reachable(): +if not archinstall.check_mirror_reachable(): log_file = os.path.join(archinstall.storage.get('LOG_PATH', None), archinstall.storage.get('LOG_FILE', None)) archinstall.log(f"Arch Linux mirrors are not reachable. Please check your internet connection and the log file '{log_file}'.", level=logging.INFO, fg="red") exit(1) -- cgit v1.2.3-54-g00ecf From b6ab6786316c5e4d8101007c4e96e64585aa7234 Mon Sep 17 00:00:00 2001 From: Anton Hvornum Date: Fri, 5 Nov 2021 16:44:51 +0100 Subject: Ignoring flake8 on blockdevice.py. --- archinstall/lib/disk/blockdevice.py | 2 ++ 1 file changed, 2 insertions(+) (limited to 'archinstall') diff --git a/archinstall/lib/disk/blockdevice.py b/archinstall/lib/disk/blockdevice.py index 8f5c0a85..fea026a1 100644 --- a/archinstall/lib/disk/blockdevice.py +++ b/archinstall/lib/disk/blockdevice.py @@ -1,3 +1,5 @@ +# flake8: noqa +# The above ignore, see issue: https://github.com/archlinux/archinstall/pull/650#issuecomment-961995949 import os import json import logging -- cgit v1.2.3-54-g00ecf