internlm/SWE-Fixer-Train-110K huggingface dataset:
Repository: archlinux/archinstall

Issue:
Create a wrapper/helper for creating folders/files with the correct chmod
One example of user-created installations can be found on @phisch's repo: https://github.com/phisch/dotfiles/blob/master/.install#L92-L100

Converting these lines into a helper wrapper that does a one-stop-shop for setting this up would at least save on complexity for both user specific setups but also some of the desktop profiles.

Parking this for v2.3.0 unless someone wants to give a stab at it.


Discussion:

Resolving patch:
diff --git a/archinstall/lib/installer.py b/archinstall/lib/installer.py
--- a/archinstall/lib/installer.py
+++ b/archinstall/lib/installer.py
@@ -1,4 +1,5 @@
 import time
+from typing import Union
 import logging
 import os
 import shutil
@@ -24,6 +25,31 @@
 __packages__ = ["base", "base-devel", "linux-firmware", "linux", "linux-lts", "linux-zen", "linux-hardened"]
 
 
+class InstallationFile:
+	def __init__(self, installation, filename, owner, mode="w"):
+		self.installation = installation
+		self.filename = filename
+		self.owner = owner
+		self.mode = mode
+		self.fh = None
+
+	def __enter__(self):
+		self.fh = open(self.filename, self.mode)
+		return self
+
+	def __exit__(self, *args):
+		self.fh.close()
+		self.installation.chown(self.owner, self.filename)
+	
+	def write(self, data :Union[str, bytes]):
+		return self.fh.write(data)
+	
+	def read(self, *args):
+		return self.fh.read(*args)
+	
+	def poll(self, *args):
+		return self.fh.poll(*args)
+
 class Installer:
 	"""
 	`Installer()` is the wrapper for most basic installation steps.
@@ -658,6 +684,12 @@ def user_set_shell(self, user, shell):
 
 		SysCommand(f"/usr/bin/arch-chroot {self.target} sh -c \"chsh -s {shell} {user}\"")
 
+	def chown(self, owner, path, options=[]):
+		return SysCommand(f"/usr/bin/arch-chroot {self.target} sh -c 'chown {' '.join(options)} {owner} {path}")
+
+	def create_file(self, filename, owner=None):
+		return InstallationFile(self, filename, owner)
+
 	def set_keyboard_language(self, language: str) -> bool:
 		if len(language.strip()):
 			if not verify_keyboard_layout(language):


Test patch:
Repository: archlinux/archinstall

Issue:
Time, Timezone and Synchronize System Clock problem!
i guess , it need "timedatectl set-ntp true" for synchronize
Time, Timezone and Synchronize System Clock problem!
i guess , it need "timedatectl set-ntp true" for synchronize


Discussion:

Resolving patch:
diff --git a/archinstall/lib/installer.py b/archinstall/lib/installer.py
--- a/archinstall/lib/installer.py
+++ b/archinstall/lib/installer.py
@@ -13,6 +13,7 @@
 from .mirrors import use_mirrors
 from .plugins import plugins
 from .storage import storage
+from .systemd import Boot
 # from .user_interaction import *
 from .output import log
 from .profiles import Profile
@@ -256,10 +257,20 @@ def set_timezone(self, zone, *args, **kwargs):
 			)
 
 	def activate_ntp(self):
-		self.log('Installing and activating NTP.', level=logging.INFO)
-		if self.pacstrap('ntp'):
-			if self.enable_service('ntpd'):
-				return True
+		log(f"activate_ntp() is deprecated, use activate_time_syncronization()", fg="yellow", level=logging.INFO)
+		self.activate_time_syncronization()
+
+	def activate_time_syncronization(self):
+		self.log('Activating systemd-timesyncd for time synchronization using Arch Linux and ntp.org NTP servers.', level=logging.INFO)
+		self.enable_service('systemd-timesyncd')
+		
+		with open(f"{self.target}/etc/systemd/timesyncd.conf", "w") as fh:
+			fh.write("[Time]\n")
+			fh.write("NTP=0.arch.pool.ntp.org 1.arch.pool.ntp.org 2.arch.pool.ntp.org 3.arch.pool.ntp.org\n")
+			fh.write("FallbackNTP=0.pool.ntp.org 1.pool.ntp.org 0.fr.pool.ntp.org\n")
+
+		with Boot(self) as session:
+			session.SysCommand(["timedatectl", "set-ntp", 'true'])
 
 	def enable_service(self, *services):
 		for service in services:
diff --git a/examples/guided.py b/examples/guided.py
--- a/examples/guided.py
+++ b/examples/guided.py
@@ -310,7 +310,7 @@ def perform_installation(mountpoint):
 				installation.set_timezone(timezone)
 
 			if archinstall.arguments.get('ntp', False):
-				installation.activate_ntp()
+				installation.activate_time_syncronization()
 
 			if (root_pw := archinstall.arguments.get('!root-password', None)) and len(root_pw):
 				installation.user_set_pw('root', root_pw)


Test patch:
Repository: archlinux/archinstall

Issue:
[2.3.0-RC1] Automatic partitioning does not fill drive with btrfs and no encryption
![btrfs-layout](https://user-images.githubusercontent.com/277927/140819976-069c8282-4fcb-4498-8f69-5a1e3e4a996c.png)

[My installation log](https://github.com/archlinux/archinstall/files/7500204/install.log.txt)



Discussion:
As discussed in discord, this is due to the elif: https://github.com/archlinux/archinstall/blob/68a1e42cfeed4c8986e7fb42330aefeb9a772710/archinstall/lib/disk/user_guides.py#L61

It doesn't get triggered when using subvolumes. The precious if block shluld increase root volume to 100% and use subvolumes

Resolving patch:
diff --git a/archinstall/lib/disk/user_guides.py b/archinstall/lib/disk/user_guides.py
--- a/archinstall/lib/disk/user_guides.py
+++ b/archinstall/lib/disk/user_guides.py
@@ -8,6 +8,10 @@ def suggest_single_disk_layout(block_device, default_filesystem=None):
 		default_filesystem = ask_for_main_filesystem_format()
 		
 	MIN_SIZE_TO_ALLOW_HOME_PART = 40 # Gb
+	using_subvolumes = False
+
+	if default_filesystem == 'btrfs':
+		using_subvolumes = input('Would you like to use BTRFS subvolumes? (Y/n): ').strip().lower() in ('', 'y', 'yes')
 
 	layout = {
 		block_device.path : {
@@ -35,14 +39,14 @@ def suggest_single_disk_layout(block_device, default_filesystem=None):
 		"start" : "513MiB",
 		"encrypted" : False,
 		"format" : True,
-		"size" : "100%" if block_device.size < MIN_SIZE_TO_ALLOW_HOME_PART else f"{min(block_device.size, 20)*1024}MiB",
+		"size" : "100%" if (using_subvolumes or block_device.size < MIN_SIZE_TO_ALLOW_HOME_PART) else f"{min(block_device.size, 20)*1024}MiB",
 		"mountpoint" : "/",
 		"filesystem" : {
 			"format" : default_filesystem
 		}
 	})
 
-	if default_filesystem == 'btrfs' and input('Would you like to use BTRFS subvolumes? (Y/n): ').strip().lower() in ('', 'y', 'yes'):
+	if default_filesystem == 'btrfs' and using_subvolumes:
 		if input('Do you want to use a recommended structure? (Y/n): ').strip().lower() in ('', 'y', 'yes'):
 			# https://btrfs.wiki.kernel.org/index.php/FAQ
 			# https://unix.stackexchange.com/questions/246976/btrfs-subvolume-uuid-clash


Test patch:
Repository: archlinux/archinstall

Issue:
AttributeError: 'NoneType' object has no attribute 'format' on master
It seams that `Getting mount information at location` is trying to lookup `/dev/sda1` instead of `/`, or something else is wrong.

![image](https://user-images.githubusercontent.com/861439/140590899-27445591-8c8b-4a69-886a-4fc6ba21e042.png)

Virtualbox 6.1


Discussion:
Could be related to #698
This also occurs as no attribute 'encrypt' depending on whether or not you try to run with encryption. I think it's a race condition as it occurs (and doesn't) using the exact same options, seemingly at random. In my opinion, this bug specifically is release blocking.

![image](https://user-images.githubusercontent.com/277927/140848596-fab8f472-2a67-4a8b-8b8a-4f4a6e9424aa.png)

Yea this one bugs me the most right now. Hard to debug as it's intermittent. But I'll add additional debug output and see if I can catch it
It's also my showstopper right now. I think it only worked for me once.
For i could glean the partitions dictionary at filesystem.py is reset/deleted during the execution of the loop at line 78
It's worth mentioning that Archinstall is single threaded and no concurrent operations.
So there has to be a step or check that's gone bad without raising an exception - allowing the code to continue.
Which is why this one becomes "tricky" to identity.

Resolving patch:
diff --git a/archinstall/lib/disk/filesystem.py b/archinstall/lib/disk/filesystem.py
--- a/archinstall/lib/disk/filesystem.py
+++ b/archinstall/lib/disk/filesystem.py
@@ -143,7 +143,10 @@ def parted(self, string: str):
 		:param string: A raw string passed to /usr/bin/parted -s <string>
 		:type string: str
 		"""
-		return self.raw_parted(string).exit_code == 0
+		if (parted_handle := self.raw_parted(string)).exit_code == 0:
+			return True
+		else:
+			raise DiskError(f"Parted failed to add a partition: {parted_handle}")
 
 	def use_entire_disk(self, root_filesystem_type='ext4') -> Partition:
 		# TODO: Implement this with declarative profiles instead.


Test patch:
Repository: archlinux/archinstall

Issue:
KeyError: '!users' btrfs + luks and root account
![Screenshot_20211111_185054](https://user-images.githubusercontent.com/45905567/141345426-430e2851-93bc-4440-8a93-f109228a0cc5.png)

heres the logs /var/log/archinstall [archinstall.zip](https://github.com/archlinux/archinstall/files/7522324/archinstall.zip)
running from master

thanks !


Discussion:

Resolving patch:
diff --git a/examples/guided.py b/examples/guided.py
--- a/examples/guided.py
+++ b/examples/guided.py
@@ -243,13 +243,13 @@ def perform_filesystem_operations():
 				fs.load_layout(archinstall.storage['disk_layouts'][drive.path])
 
 def perform_installation(mountpoint):
-	user_credentials = {
-		"!users" : archinstall.arguments['!users'],
-		"!superusers" : archinstall.arguments['!superusers'],
-		"!root-password" : archinstall.arguments['!root-password'],
-	}
+	user_credentials = {}
+	if archinstall.arguments.get('!users'):
+		user_credentials["!users"] = archinstall.arguments['!users']
+	if archinstall.arguments.get('!superusers'):
+		user_credentials["!superusers"] = archinstall.arguments['!superusers']
 	if archinstall.arguments.get('!encryption-password'):
-		user_credentials["!encryption-password"] = archinstall.arguments.get('!encryption-password')
+		user_credentials["!encryption-password"] = archinstall.arguments['!encryption-password']
 
 	with open("/var/log/archinstall/user_credentials.json", "w") as config_file:
 		config_file.write(json.dumps(user_credentials, indent=4, sort_keys=True, cls=archinstall.UNSAFE_JSON))


Test patch:
Repository: archlinux/archinstall

Issue:
Install failed, key error "Encrypted"
During manual disk partitioning, you can realize that the "encrypted" key is not created in the dictionary, resulting in the error as we see below:

```log
{
    "/dev/sda": {
        "partitions": [
            {
                "boot": true,
                "filesystem": {
                    "format": "fat32"
                },
                "format": true,
                "mountpoint": "/boot",
                "size": "600MiB",
                "start": "1MiB",
                "type": "primary",
                "wipe": true
            },
            {
                "filesystem": {
                    "format": "ext4"
                },
                "format": true,
                "mountpoint": "/",
                "size": "100%",
                "start": "600MiB",
                "type": "primary",
                "wipe": true
            }
        ]
    }
}
Kept partition format 1 for BlockDevice(/dev/sda, size=223.6GB, free_space=240GB, bus_type=sata)
Adding partition to BlockDevice(/dev/sda, size=223.6GB, free_space=240GB, bus_type=sata), 1MiB->600MiB
Getting mount information for device path /dev/sda1
Formatting /dev/sda1 -> fat32
Setting boot on on (parted) partition index 1
Adding partition to BlockDevice(/dev/sda, size=223.6GB, free_space=1031kB+239GB, bus_type=sata), 600MiB->100%
Getting mount information for device path /dev/sda2
Formatting /dev/sda2 -> ext4
'encrypted'
```

![error](https://i.postimg.cc/tT2T3mZY/error-min.jpg)

A temporary solution for this is to manually activate disk encryption, then disable it.


Discussion:

Resolving patch:
diff --git a/archinstall/lib/installer.py b/archinstall/lib/installer.py
--- a/archinstall/lib/installer.py
+++ b/archinstall/lib/installer.py
@@ -175,7 +175,7 @@ def mount_ordered_layout(self, layouts :dict):
 
 		for mountpoint in sorted(mountpoints.keys()):
 			log(f"Mounting {mountpoint} to {self.target}{mountpoint}", level=logging.INFO)
-			if mountpoints[mountpoint]['encrypted']:
+			if mountpoints[mountpoint].get('encrypted', False):
 				loopdev = storage.get('ENC_IDENTIFIER', 'ai') + 'loop'
 				if not (password := mountpoints[mountpoint].get('!password', None)):
 					raise RequirementError(f"Missing mountpoint {mountpoint} encryption password in layout: {mountpoints[mountpoint]}")


Test patch:
Repository: archlinux/archinstall

Issue:
[2.3.0-RC1] --config file parsing regressions
When specifying a config file generated from /var/log/archinstall/user_configuration.json to attempt to retry the same installation, I ran into hardware related import errors until I dropped gfx_driver from the config file, and then once I did, the installer was prompting me to re-enter a lot of entries (not imported properly), even though they seemed to be in the configuration file.


Discussion:
I've confirmed the issue but still haven't figured out where the issue is.
I'll fix this before RC2 is released. This is the last and final issue before RC2 can get out.

Resolving patch:
diff --git a/archinstall/__init__.py b/archinstall/__init__.py
--- a/archinstall/__init__.py
+++ b/archinstall/__init__.py
@@ -49,12 +49,15 @@ def initialize_arguments():
 				with urllib.request.urlopen(urllib.request.Request(args.config, headers={'User-Agent': 'ArchInstall'})) as response:
 					config = json.loads(response.read())
 		except Exception as e:
-			print(e)
+			raise ValueError(f"Could not load --config because: {e}")
+	
 		if args.creds is not None:
 			with open(args.creds) as file:
 				config.update(json.load(file))
+	
 		# Installation can't be silent if config is not passed
 		config["silent"] = args.silent
+	
 	for arg in unknowns:
 		if '--' == arg[:2]:
 			if '=' in arg:
@@ -62,9 +65,12 @@ def initialize_arguments():
 			else:
 				key, val = arg[2:], True
 			config[key] = val
+	
 	config["script"] = args.script
+	
 	if args.dry_run is not None:
 		config["dry-run"] = args.dry_run
+
 	return config
 
 
diff --git a/archinstall/lib/systemd.py b/archinstall/lib/systemd.py
--- a/archinstall/lib/systemd.py
+++ b/archinstall/lib/systemd.py
@@ -96,7 +96,7 @@ def __exit__(self, *args, **kwargs):
 		if shutdown.exit_code == 0:
 			storage['active_boot'] = None
 		else:
-			raise SysCallError(f"Could not shut down temporary boot of {self.instance}", level=logging.ERROR, fg="red")
+			raise SysCallError(f"Could not shut down temporary boot of {self.instance}: {shutdown}", exit_code=shutdown.exit_code)
 
 	def __iter__(self):
 		if self.session:


Test patch:
Repository: archlinux/archinstall

Issue:
[2.3.0RC2] [VM] Can't create a filesystem on a new partition during the manual partitioning
During the manual partitioning, if you select to ''Create a new partition'' and later write a filesystem when archinstall asks for one, it'll crash after writing the name of filesystem.

![2021-11-21_00-14-40](https://user-images.githubusercontent.com/53870341/142741251-742a1fdb-c900-44cc-9227-a8f0a29ab4a4.png)



Discussion:
Thank you for this feedback, the manual partitioning is the least tested - so this is extremely valuable! :D
I'll investigate during the weekend.

Resolving patch:
diff --git a/archinstall/lib/disk/blockdevice.py b/archinstall/lib/disk/blockdevice.py
--- a/archinstall/lib/disk/blockdevice.py
+++ b/archinstall/lib/disk/blockdevice.py
@@ -192,7 +192,7 @@ def free_space(self):
 
 	@property
 	def largest_free_space(self):
-		info = None
+		info = []
 		for space_info in self.free_space:
 			if not info:
 				info = space_info
@@ -202,6 +202,22 @@ def largest_free_space(self):
 					info = space_info
 		return info
 
+	@property
+	def first_free_sector(self):
+		if info := self.largest_free_space:
+			start = info[0]
+		else:
+			start = '512MB'
+		return start
+
+	@property
+	def first_end_sector(self):
+		if info := self.largest_free_space:
+			end = info[1]
+		else:
+			end = f"{self.size}GB"
+		return end
+
 	def partprobe(self):
 		SysCommand(['partprobe', self.path])
 
diff --git a/archinstall/lib/user_interaction.py b/archinstall/lib/user_interaction.py
--- a/archinstall/lib/user_interaction.py
+++ b/archinstall/lib/user_interaction.py
@@ -643,10 +643,10 @@ def manage_new_and_existing_partitions(block_device :BlockDevice) -> dict:
 
 			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()
+			start = input(f"Enter the start sector (percentage or block number, default: {block_device.first_free_sector}): ").strip()
 			if not start.strip():
-				start = block_device.largest_free_space[0]
-				end_suggested = block_device.largest_free_space[1]
+				start = block_device.first_free_sector
+				end_suggested = block_device.first_end_sector
 			else:
 				end_suggested = '100%'
 			end = input(f"Enter the end sector of the partition (percentage or block number, ex: {end_suggested}): ").strip()


Test patch:
Repository: archlinux/archinstall

Issue:
in xfce, it need xarchiver for create archive & extract here-to
in xfce, it need xarchiver for create archive & extract here-to
in xfce, it need xarchiver for create archive & extract here-to
in xfce, it need xarchiver for create archive & extract here-to


Discussion:
Thanks for reporting these, I'm testing it right now and will most likely push a PR to address these later tonight.
> Thanks for reporting these, I'm testing it right now and will most likely push a PR to address these later tonight.

If we're going to add this, might as well add ark to kde.
Thanks for reporting these, I'm testing it right now and will most likely push a PR to address these later tonight.
> Thanks for reporting these, I'm testing it right now and will most likely push a PR to address these later tonight.

If we're going to add this, might as well add ark to kde.

Resolving patch:
diff --git a/profiles/kde.py b/profiles/kde.py
--- a/profiles/kde.py
+++ b/profiles/kde.py
@@ -9,6 +9,7 @@
 	"konsole",
 	"kate",
 	"dolphin",
+	"ark",
 	"sddm",
 	"plasma-wayland-session",
 	"egl-wayland",
diff --git a/profiles/xfce4.py b/profiles/xfce4.py
--- a/profiles/xfce4.py
+++ b/profiles/xfce4.py
@@ -12,6 +12,7 @@
 	"lightdm-gtk-greeter",
 	"gvfs",
 	"network-manager-applet",
+	"xarchiver"
 ]
 
 


Test patch:
Repository: archlinux/archinstall

Issue:
mkinitcpio.conf generated incorrectly for AMDGPU.
As the archwiki installation guide states [https://wiki.archlinux.org/title/AMDGPU#Specify_the_correct_module_order](https://wiki.archlinux.org/title/AMDGPU#Specify_the_correct_module_order), you must ensure that the amdgpu module is loaded before the radeon one: `MODULES=(amdgpu radeon)`
Otherwise the DM will fail to start at boot.


Discussion:
We'll have to implement a package log in: https://github.com/archlinux/archinstall/blob/638a05243c7bab7db7449c24a2ab770e581244d0/archinstall/lib/installer.py#L264

And then in the xorg profile create a similar conditional update on https://github.com/archlinux/archinstall/blob/d2a4572e98044d4af504aabd0203b6c89e9991bf/profiles/xorg.py#L40

Resolving patch:
diff --git a/profiles/xorg.py b/profiles/xorg.py
--- a/profiles/xorg.py
+++ b/profiles/xorg.py
@@ -45,6 +45,17 @@ def _prep_function(*args, **kwargs):
 				archinstall.storage['installation_session'].add_additional_packages("xorg-server xorg-xinit nvidia-dkms")
 			else:
 				archinstall.storage['installation_session'].add_additional_packages(f"xorg-server xorg-xinit {' '.join(archinstall.storage.get('gfx_driver_packages', []))}")
+		elif 'amdgpu' in archinstall.storage.get("gfx_driver_packages", []):
+			# The order of these two are important if amdgpu is installed #808
+			if 'amdgpu' in archinstall.storage['installation_session'].MODULES:
+				archinstall.storage['installation_session'].MODULES.remove('amdgpu')
+			archinstall.storage['installation_session'].MODULES.append('amdgpu')
+
+			if 'radeon' in archinstall.storage['installation_session'].MODULES:
+				archinstall.storage['installation_session'].MODULES.remove('radeon')
+			archinstall.storage['installation_session'].MODULES.append('radeon')
+
+			archinstall.storage['installation_session'].add_additional_packages(f"xorg-server xorg-xinit {' '.join(archinstall.storage.get('gfx_driver_packages', []))}")
 		else:
 			archinstall.storage['installation_session'].add_additional_packages(f"xorg-server xorg-xinit {' '.join(archinstall.storage.get('gfx_driver_packages', []))}")
 	except Exception as err:


Test patch:
Repository: archlinux/archinstall

Issue:
Problem on master startup
After the last merges (the typing one) start fail with following error
```
werner@xerneas archinstall]$ sudo python -m archinstall 
Traceback (most recent call last):
  File "/usr/lib/python3.10/runpy.py", line 187, in _run_module_as_main
    mod_name, mod_spec, code = _get_module_details(mod_name, _Error)
  File "/usr/lib/python3.10/runpy.py", line 146, in _get_module_details
    return _get_module_details(pkg_main_name, error)
  File "/usr/lib/python3.10/runpy.py", line 110, in _get_module_details
    __import__(pkg_name)
  File "/home/werner/projects/archinstall/archinstall/__init__.py", line 11, in <module>
    from .lib.installer import __packages__, Installer, accessibility_tools_in_use
  File "/home/werner/projects/archinstall/archinstall/lib/installer.py", line 9, in <module>
    from typing import Union, Dict, Any, List, ModuleType, Optional, Iterator, Mapping
ImportError: cannot import name 'ModuleType' from 'typing' (/usr/lib/python3.10/typing.py)

```
(edited.  ModuleType is not documented at [the documentation](https://docs.python.org/3/library/typing.html)


Discussion:
A s*** it's [types.ModuleType](https://docs.python.org/3/library/types.html#types.ModuleType) and not `typing.ModuleType`.. I'll fix a PR right away.

Resolving patch:
diff --git a/archinstall/lib/installer.py b/archinstall/lib/installer.py
--- a/archinstall/lib/installer.py
+++ b/archinstall/lib/installer.py
@@ -6,7 +6,8 @@
 import pathlib
 import subprocess
 import glob
-from typing import Union, Dict, Any, List, ModuleType, Optional, Iterator, Mapping
+from types import ModuleType
+from typing import Union, Dict, Any, List, Optional, Iterator, Mapping
 from .disk import get_partitions_in_use, Partition
 from .general import SysCommand, generate_password
 from .hardware import has_uefi, is_vm, cpu_vendor
diff --git a/archinstall/lib/plugins.py b/archinstall/lib/plugins.py
--- a/archinstall/lib/plugins.py
+++ b/archinstall/lib/plugins.py
@@ -7,7 +7,8 @@
 import urllib.parse
 import urllib.request
 from importlib import metadata
-from typing import ModuleType, Optional, List
+from typing import Optional, List
+from types import ModuleType
 
 from .output import log
 from .storage import storage
diff --git a/archinstall/lib/profiles.py b/archinstall/lib/profiles.py
--- a/archinstall/lib/profiles.py
+++ b/archinstall/lib/profiles.py
@@ -9,7 +9,8 @@
 import urllib.error
 import urllib.parse
 import urllib.request
-from typing import Optional, ModuleType, Dict, Union, TYPE_CHECKING
+from typing import Optional, Dict, Union, TYPE_CHECKING
+from types import ModuleType
 # https://stackoverflow.com/a/39757388/929999
 if TYPE_CHECKING:
 	from .installer import Installer


Test patch: