Send patches - preferably formatted by git format-patch - to patches at archlinux32 dot org.
summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--README.md4
-rw-r--r--archinstall/__init__.py2
-rw-r--r--archinstall/lib/disk.py53
-rw-r--r--archinstall/lib/hardware.py7
-rw-r--r--archinstall/lib/installer.py30
-rw-r--r--archinstall/lib/profiles.py22
-rw-r--r--docs/archinstall/general.rst7
-rw-r--r--docs/index.rst2
-rw-r--r--docs/installing/guided.rst2
-rw-r--r--examples/guided.py8
-rw-r--r--examples/minimal.py2
-rw-r--r--profiles/52-54-00-12-34-56.py2
-rw-r--r--profiles/applications/awesome.py6
-rw-r--r--profiles/awesome.py10
14 files changed, 111 insertions, 46 deletions
diff --git a/README.md b/README.md
index c1ec746e..5451b55f 100644
--- a/README.md
+++ b/README.md
@@ -57,10 +57,10 @@ with archinstall.Filesystem(harddrive, archinstall.GPT) as fs:
This installer will perform the following:
* Prompt the user to select a disk and disk-password
- * Proceed to wipe the selected disk with a `GPT` partition table.
+ * Proceed to wipe the selected disk with a `GPT` partition table on a UEFI system and MBR on a bios system.
* Sets up a default 100% used disk with encryption.
* Installs a basic instance of Arch Linux *(base base-devel linux linux-firmware btrfs-progs efibootmgr)*
- * Installs and configures a bootloader to partition 0.
+ * Installs and configures a bootloader to partition 0 on uefi. on bios it sets the root to partition 0.
* Install additional packages *(nano, wget, git)*
* Installs a network-profile called [awesome](https://github.com/Torxed/archinstall/blob/master/profiles/awesome.py) *(more on network profiles in the documentation)*
diff --git a/archinstall/__init__.py b/archinstall/__init__.py
index d4452d38..91cf17be 100644
--- a/archinstall/__init__.py
+++ b/archinstall/__init__.py
@@ -2,7 +2,7 @@ from .lib.general import *
from .lib.disk import *
from .lib.user_interaction import *
from .lib.exceptions import *
-from .lib.installer import *
+from .lib.installer import __packages__, __base_packages__, Installer
from .lib.profiles import *
from .lib.luks import *
from .lib.mirrors import *
diff --git a/archinstall/lib/disk.py b/archinstall/lib/disk.py
index 9ad49ac2..fdc2fbc5 100644
--- a/archinstall/lib/disk.py
+++ b/archinstall/lib/disk.py
@@ -5,6 +5,7 @@ from .exceptions import DiskError
from .general import *
from .output import log, LOG_LEVELS
from .storage import storage
+from .hardware import hasUEFI
ROOT_DIR_PATTERN = re.compile('^.*?/devices')
GPT = 0b00000001
@@ -389,7 +390,7 @@ class Filesystem():
# TODO:
# When instance of a HDD is selected, check all usages and gracefully unmount them
# as well as close any crypto handles.
- def __init__(self, blockdevice, mode=GPT):
+ def __init__(self, blockdevice,mode):
self.blockdevice = blockdevice
self.mode = mode
@@ -402,6 +403,11 @@ class Filesystem():
return self
else:
raise DiskError(f'Problem setting the partition format to GPT:', f'/usr/bin/parted -s {self.blockdevice.device} mklabel gpt')
+ elif self.mode == MBR:
+ if sys_command(f'/usr/bin/parted -s {self.blockdevice.device} mklabel msdos').exit_code == 0:
+ return self
+ else:
+ raise DiskError(f'Problem setting the partition format to GPT:', f'/usr/bin/parted -s {self.blockdevice.device} mklabel msdos')
else:
raise DiskError(f'Unknown mode selected to format in: {self.mode}')
@@ -444,28 +450,39 @@ class Filesystem():
def use_entire_disk(self, root_filesystem_type='ext4'):
log(f"Using and formatting the entire {self.blockdevice}.", level=LOG_LEVELS.Debug)
- self.add_partition('primary', start='1MiB', end='513MiB', format='fat32')
- self.set_name(0, 'EFI')
- self.set(0, 'boot on')
- # TODO: Probably redundant because in GPT mode 'esp on' is an alias for "boot on"?
- # https://www.gnu.org/software/parted/manual/html_node/set.html
- self.set(0, 'esp on')
- self.add_partition('primary', start='513MiB', end='100%')
-
- self.blockdevice.partition[0].filesystem = 'vfat'
- self.blockdevice.partition[1].filesystem = root_filesystem_type
- log(f"Set the root partition {self.blockdevice.partition[1]} to use filesystem {root_filesystem_type}.", level=LOG_LEVELS.Debug)
-
- self.blockdevice.partition[0].target_mountpoint = '/boot'
- self.blockdevice.partition[1].target_mountpoint = '/'
-
- self.blockdevice.partition[0].allow_formatting = True
- self.blockdevice.partition[1].allow_formatting = True
+ if hasUEFI():
+ self.add_partition('primary', start='1MiB', end='513MiB', format='fat32')
+ self.set_name(0, 'EFI')
+ self.set(0, 'boot on')
+ # TODO: Probably redundant because in GPT mode 'esp on' is an alias for "boot on"?
+ # https://www.gnu.org/software/parted/manual/html_node/set.html
+ self.set(0, 'esp on')
+ self.add_partition('primary', start='513MiB', end='100%')
+
+ self.blockdevice.partition[0].filesystem = 'vfat'
+ self.blockdevice.partition[1].filesystem = root_filesystem_type
+ log(f"Set the root partition {self.blockdevice.partition[1]} to use filesystem {root_filesystem_type}.", level=LOG_LEVELS.Debug)
+
+ self.blockdevice.partition[0].target_mountpoint = '/boot'
+ self.blockdevice.partition[1].target_mountpoint = '/'
+
+ self.blockdevice.partition[0].allow_formatting = True
+ self.blockdevice.partition[1].allow_formatting = True
+ else:
+ #we don't need a seprate boot partition it would be a waste of space
+ self.add_partition('primary', start='1MB', end='100%')
+ self.blockdevice.partition[0].filesystem=root_filesystem_type
+ log(f"Set the root partition {self.blockdevice.partition[0]} to use filesystem {root_filesystem_type}.", level=LOG_LEVELS.Debug)
+ self.blockdevice.partition[0].target_mountpoint = '/'
+ self.blockdevice.partition[0].allow_formatting = True
def add_partition(self, type, start, end, format=None):
log(f'Adding partition to {self.blockdevice}', level=LOG_LEVELS.Info)
previous_partitions = self.blockdevice.partitions
+ if self.mode == MBR:
+ if len(self.blockdevice.partitions)>3:
+ DiskError("Too many partitions on disk, MBR disks can only have 3 parimary partitions")
if format:
partitioning = self.parted(f'{self.blockdevice.device} mkpart {type} {format} {start} {end}') == 0
else:
diff --git a/archinstall/lib/hardware.py b/archinstall/lib/hardware.py
index 5828fd09..10f3970f 100644
--- a/archinstall/lib/hardware.py
+++ b/archinstall/lib/hardware.py
@@ -1,10 +1,15 @@
-import os
+import os, subprocess
from .general import sys_command
from .networking import list_interfaces, enrichIfaceTypes
def hasWifi():
return 'WIRELESS' in enrichIfaceTypes(list_interfaces().values()).values()
+def hasAMDCPU():
+ if subprocess.check_output("lscpu | grep AMD", shell=True).strip().decode():
+ return True
+ return False
+
def hasUEFI():
return os.path.isdir('/sys/firmware/efi')
diff --git a/archinstall/lib/installer.py b/archinstall/lib/installer.py
index d161c3b7..2ffcb007 100644
--- a/archinstall/lib/installer.py
+++ b/archinstall/lib/installer.py
@@ -1,4 +1,4 @@
-import os, stat, time, shutil, pathlib
+import os, stat, time, shutil, pathlib, subprocess
from .exceptions import *
from .disk import *
@@ -10,6 +10,10 @@ from .systemd import Networkd
from .output import log, LOG_LEVELS
from .storage import storage
+# Any package that the Installer() is responsible for (optional and the default ones)
+__packages__ = ["base", "base-devel", "linux", "linux-firmware", "efibootmgr", "nano", "ntp", "iwd"]
+__base_packages__ = __packages__[:6]
+
class Installer():
"""
`Installer()` is the wrapper for most basic installation steps.
@@ -34,7 +38,7 @@ class Installer():
:type hostname: str, optional
"""
- def __init__(self, partition, boot_partition, *, base_packages='base base-devel linux linux-firmware efibootmgr nano', profile=None, mountpoint='/mnt', hostname='ArchInstalled', logdir=None, logfile=None):
+ def __init__(self, partition, boot_partition, *, base_packages=__base_packages__, profile=None, mountpoint='/mnt', hostname='ArchInstalled', logdir=None, logfile=None):
self.profile = profile
self.hostname = hostname
self.mountpoint = mountpoint
@@ -52,7 +56,7 @@ class Installer():
'user' : False # Root counts as a user, if additional users are skipped.
}
- self.base_packages = base_packages.split(' ')
+ self.base_packages = base_packages.split(' ') if type(base_packages) is str else base_packages
self.post_base_install = []
storage['session'] = self
@@ -67,9 +71,11 @@ class Installer():
log(*args, level=level, **kwargs)
def __enter__(self, *args, **kwargs):
- self.partition.mount(self.mountpoint)
- os.makedirs(f'{self.mountpoint}/boot', exist_ok=True)
- self.boot_partition.mount(f'{self.mountpoint}/boot')
+ if hasUEFI():
+ # on bios we don't have a boot partition
+ self.partition.mount(self.mountpoint)
+ os.makedirs(f'{self.mountpoint}/boot', exist_ok=True)
+ self.boot_partition.mount(f'{self.mountpoint}/boot')
return self
def __exit__(self, *args, **kwargs):
@@ -329,6 +335,8 @@ class Installer():
self.log(f'Adding bootloader {bootloader} to {self.boot_partition}', level=LOG_LEVELS.Info)
if bootloader == 'systemd-bootctl':
+ if not hasUEFI():
+ raise HardwareIncompatibilityError
# TODO: Ideally we would want to check if another config
# points towards the same disk and/or partition.
# And in which case we should do some clean up.
@@ -398,6 +406,16 @@ class Installer():
break
raise RequirementError(f"Could not identify the UUID of {self.partition}, there for {self.mountpoint}/boot/loader/entries/arch.conf will be broken until fixed.")
+ elif bootloader == "grub-install":
+ if hasUEFI():
+ o = b''.join(sys_command(f'/usr/bin/arch-chroot {self.mountpoint} grub-install --target=x86_64-efi --efi-directory=/boot --bootloader-id=GRUB'))
+ sys_command('/usr/bin/arch-chroot grub-mkconfig -o /boot/grub/grub.cfg')
+ else:
+ root_device = subprocess.check_output(f'basename "$(readlink -f "/sys/class/block/{self.partition.path.strip("/dev/")}/..")',shell=True).decode().strip()
+ if root_device == "block":
+ root_device = f"{self.partition.path}"
+ o = b''.join(sys_command(f'/usr/bin/arch-chroot {self.mountpoint} grub-install --target=--target=i386-pc /dev/{root_device}'))
+ sys_command('/usr/bin/arch-chroot grub-mkconfig -o /boot/grub/grub.cfg')
else:
raise RequirementError(f"Unknown (or not yet implemented) bootloader added to add_bootloader(): {bootloader}")
diff --git a/archinstall/lib/profiles.py b/archinstall/lib/profiles.py
index 08b1d618..8198ff11 100644
--- a/archinstall/lib/profiles.py
+++ b/archinstall/lib/profiles.py
@@ -178,6 +178,28 @@ class Profile(Script):
return True
return False
+ @property
+ def packages(self) -> list:
+ """
+ Returns a list of packages baked into the profile definition.
+ If no package definition has been done, .packages() will return None.
+ """
+ with open(self.path, 'r') as source:
+ source_data = source.read()
+
+ # Some crude safety checks, make sure the imported profile has
+ # a __name__ check before importing.
+ #
+ # If the requirements are met, import with .py in the namespace to not
+ # trigger a traditional:
+ # if __name__ == 'moduleName'
+ if '__name__' in source_data and '__packages__' in source_data:
+ with self.load_instructions(namespace=f"{self.namespace}.py") as imported:
+ if hasattr(imported, '__packages__'):
+ return imported.__packages__
+ return None
+
+
class Application(Profile):
def __repr__(self, *args, **kwargs):
return f'Application({os.path.basename(self.profile)})'
diff --git a/docs/archinstall/general.rst b/docs/archinstall/general.rst
index 349393de..e5459749 100644
--- a/docs/archinstall/general.rst
+++ b/docs/archinstall/general.rst
@@ -22,7 +22,10 @@ Locale related
.. autofunction:: archinstall.search_keyboard_layout
-.. autofunction:: archinstall.set_keyboard_layout
+.. autofunction:: archinstall.set_keyboard_language
+
+..
+ autofunction:: archinstall.Installer.set_keyboard_layout
Services
========
@@ -34,7 +37,7 @@ Mirrors
.. autofunction:: archinstall.filter_mirrors_by_region
-.. autofunction:: archinstall.add_custom_mirror
+.. autofunction:: archinstall.add_custom_mirrors
.. autofunction:: archinstall.insert_mirrors
diff --git a/docs/index.rst b/docs/index.rst
index eef368c5..fea8f788 100644
--- a/docs/index.rst
+++ b/docs/index.rst
@@ -43,12 +43,14 @@ Some of the features of Archinstall are:
examples/python
examples/binary
+..
examples/scripting
.. toctree::
:maxdepth: 3
:caption: Programming Guide
+..
programming_guide/requirements
programming_guide/basic_concept
diff --git a/docs/installing/guided.rst b/docs/installing/guided.rst
index 7ce081ca..40d86055 100644
--- a/docs/installing/guided.rst
+++ b/docs/installing/guided.rst
@@ -1,5 +1,3 @@
-.. _installing.guided:
-
Guided installation
===================
diff --git a/examples/guided.py b/examples/guided.py
index 71e1e01d..f374a41c 100644
--- a/examples/guided.py
+++ b/examples/guided.py
@@ -1,5 +1,6 @@
import getpass, time, json, sys, signal, os
import archinstall
+from archinstall.lib.hardware import hasUEFI
"""
This signal-handler chain (and global variable)
@@ -244,7 +245,12 @@ def perform_installation_steps():
Setup the blockdevice, filesystem (and optionally encryption).
Once that's done, we'll hand over to perform_installation()
"""
- with archinstall.Filesystem(archinstall.arguments['harddrive'], archinstall.GPT) as fs:
+ # maybe we can ask the user what they would prefer on uefi systems?
+ if hasUEFI():
+ mode = archinstall.GPT
+ else:
+ mode = archinstall.MBR
+ with archinstall.Filesystem(archinstall.arguments['harddrive'],mode) as fs:
# Wipe the entire drive if the disk flag `keep_partitions`is False.
if archinstall.arguments['harddrive'].keep_partitions is False:
fs.use_entire_disk(root_filesystem_type=archinstall.arguments.get('filesystem', 'btrfs'))
diff --git a/examples/minimal.py b/examples/minimal.py
index 664bad0d..b5bb34e0 100644
--- a/examples/minimal.py
+++ b/examples/minimal.py
@@ -8,7 +8,7 @@ archinstall.sys_command(f'cryptsetup close /dev/mapper/luksloop', suppress_error
harddrive = archinstall.select_disk(archinstall.all_disks())
disk_password = getpass.getpass(prompt='Disk password (won\'t echo): ')
-with archinstall.Filesystem(harddrive, archinstall.GPT) as fs:
+with archinstall.Filesystem(harddrive) as fs:
# Use the entire disk instead of setting up partitions on your own
fs.use_entire_disk('luks2')
diff --git a/profiles/52-54-00-12-34-56.py b/profiles/52-54-00-12-34-56.py
index 679c6721..ed2c9d78 100644
--- a/profiles/52-54-00-12-34-56.py
+++ b/profiles/52-54-00-12-34-56.py
@@ -11,7 +11,7 @@ archinstall.sys_command(f'cryptsetup close /dev/mapper/luksloop', suppress_error
harddrive = archinstall.all_disks()['/dev/sda']
disk_password = '1234'
-with archinstall.Filesystem(harddrive, archinstall.GPT) as fs:
+with archinstall.Filesystem(harddrive) as fs:
# Use the entire disk instead of setting up partitions on your own
fs.use_entire_disk('luks2')
diff --git a/profiles/applications/awesome.py b/profiles/applications/awesome.py
index 578f246e..b8d779c0 100644
--- a/profiles/applications/awesome.py
+++ b/profiles/applications/awesome.py
@@ -1,10 +1,10 @@
import archinstall
+__packages__ = ["awesome", "xorg-xrandr", "xterm", "feh", "slock", "terminus-font", "gnu-free-fonts", "ttf-liberation", "xsel"]
+
installation.install_profile('xorg')
-installation.add_additional_packages(
- "awesome xorg-xrandr xterm feh slock terminus-font gnu-free-fonts ttf-liberation xsel"
-)
+installation.add_additional_packages(__packages__)
with open(f'{installation.mountpoint}/etc/X11/xinit/xinitrc', 'r') as xinitrc:
xinitrc_data = xinitrc.read()
diff --git a/profiles/awesome.py b/profiles/awesome.py
index b914b175..8004fc62 100644
--- a/profiles/awesome.py
+++ b/profiles/awesome.py
@@ -2,6 +2,7 @@
import archinstall
+__packages__ = ['nano', 'nemo', 'gpicview-gtk3', 'chromium', 'openssh', 'sshfs', 'htop', 'scrot', 'wget']
def _prep_function(*args, **kwargs):
"""
@@ -28,14 +29,7 @@ if __name__ == 'awesome':
awesome = archinstall.Application(installation, 'awesome')
awesome.install()
- # Then setup and configure the desktop environment: awesome
- editor = "nano"
- filebrowser = "nemo gpicview-gtk3"
- webbrowser = "chromium" # TODO: Ask the user to select one instead
- utils = "openssh sshfs htop scrot wget"
-
-
- installation.add_additional_packages(f"{webbrowser} {utils} {filebrowser} {editor}")
+ installation.add_additional_packages(__packages__)
alacritty = archinstall.Application(installation, 'alacritty')
alacritty.install()