Merged in latest changes from master
This commit is contained in:
commit
515cd4daf0
|
|
@ -15,6 +15,9 @@ on:
|
|||
- '**.md'
|
||||
- 'LICENSE'
|
||||
- 'PKGBUILD'
|
||||
release:
|
||||
types:
|
||||
- created
|
||||
|
||||
jobs:
|
||||
build:
|
||||
|
|
|
|||
|
|
@ -24,7 +24,7 @@ Or use `pip install --upgrade archinstall` to use as a library.
|
|||
|
||||
Assuming you are on an Arch Linux live-ISO and booted into EFI mode.
|
||||
|
||||
# python -m archinstall --script guided
|
||||
# archinstall
|
||||
|
||||
|
||||
## Running from a declarative configuration file or URL
|
||||
|
|
@ -34,7 +34,7 @@ Prequisites:
|
|||
|
||||
Assuming you are on a Arch Linux live-ISO and booted into EFI mode.
|
||||
|
||||
# python -m archinstall --config <path to config file or URL> --vars '<space_seperated KEY=VALUE pairs>'
|
||||
# archinstall --config <path to config file or URL> [optional: --vars '<space_seperated KEY=VALUE pairs>']
|
||||
|
||||
# Help?
|
||||
|
||||
|
|
|
|||
|
|
@ -23,7 +23,7 @@ from .lib.user_interaction import *
|
|||
|
||||
parser = ArgumentParser()
|
||||
|
||||
__version__ = "2.2.0.dev1"
|
||||
__version__ = "2.2.0.RC1"
|
||||
|
||||
|
||||
def initialize_arguments():
|
||||
|
|
@ -32,16 +32,7 @@ def initialize_arguments():
|
|||
parser.add_argument("--silent", action="store_true",
|
||||
help="Warning!!! No prompts, ignored if config is not passed")
|
||||
parser.add_argument("--script", default="guided", nargs="?", help="Script to run for installation", type=str)
|
||||
parser.add_argument("--vars",
|
||||
metavar="KEY=VALUE",
|
||||
nargs='?',
|
||||
help="Set a number of key-value pairs "
|
||||
"(do not put spaces before or after the = sign). "
|
||||
"If a value contains spaces, you should define "
|
||||
"it with double quotes: "
|
||||
'foo="this is a sentence". Note that '
|
||||
"values are always treated as strings.")
|
||||
args = parser.parse_args()
|
||||
args, unknowns = parser.parse_known_args()
|
||||
if args.config is not None:
|
||||
try:
|
||||
# First, let's check if this is a URL scheme instead of a filename
|
||||
|
|
@ -57,13 +48,13 @@ def initialize_arguments():
|
|||
print(e)
|
||||
# Installation can't be silent if config is not passed
|
||||
config["silent"] = args.silent
|
||||
if args.vars is not None:
|
||||
try:
|
||||
for var in args.vars.split(' '):
|
||||
key, val = var.split("=")
|
||||
config[key] = val
|
||||
except Exception as e:
|
||||
print(e)
|
||||
for arg in unknowns:
|
||||
if '--' == arg[:2]:
|
||||
if '=' in arg:
|
||||
key, val = [x.strip() for x in arg[2:].split('=', 1)]
|
||||
else:
|
||||
key, val = arg[2:], True
|
||||
config[key] = val
|
||||
config["script"] = args.script
|
||||
return config
|
||||
|
||||
|
|
|
|||
|
|
@ -333,6 +333,10 @@ class SysCommand:
|
|||
while self.session.ended is None:
|
||||
self.session.poll()
|
||||
|
||||
if self.peak_output:
|
||||
sys.stdout.write('\n')
|
||||
sys.stdout.flush()
|
||||
|
||||
except SysCallError:
|
||||
return False
|
||||
|
||||
|
|
|
|||
|
|
@ -1,6 +1,6 @@
|
|||
from .disk import *
|
||||
from .hardware import *
|
||||
from .locale_helpers import verify_x11_keyboard_layout
|
||||
from .locale_helpers import verify_keyboard_layout, verify_x11_keyboard_layout
|
||||
from .mirrors import *
|
||||
from .storage import storage
|
||||
from .user_interaction import *
|
||||
|
|
@ -453,6 +453,7 @@ class Installer:
|
|||
self.pacstrap('efibootmgr')
|
||||
o = b''.join(SysCommand(f'/usr/bin/arch-chroot {self.target} grub-install --target=x86_64-efi --efi-directory=/boot --bootloader-id=GRUB'))
|
||||
SysCommand('/usr/bin/arch-chroot /mnt grub-mkconfig -o /boot/grub/grub.cfg')
|
||||
self.helper_flags['bootloader'] = True
|
||||
return True
|
||||
else:
|
||||
root_device = subprocess.check_output(f'basename "$(readlink -f /sys/class/block/{root_partition.path.replace("/dev/", "")}/..)"', shell=True).decode().strip()
|
||||
|
|
@ -460,7 +461,7 @@ class Installer:
|
|||
root_device = f"{root_partition.path}"
|
||||
o = b''.join(SysCommand(f'/usr/bin/arch-chroot {self.target} grub-install --target=i386-pc /dev/{root_device}'))
|
||||
SysCommand('/usr/bin/arch-chroot /mnt grub-mkconfig -o /boot/grub/grub.cfg')
|
||||
self.helper_flags['bootloader'] = bootloader
|
||||
self.helper_flags['bootloader'] = True
|
||||
return True
|
||||
else:
|
||||
raise RequirementError(f"Unknown (or not yet implemented) bootloader requested: {bootloader}")
|
||||
|
|
@ -546,6 +547,8 @@ class Installer:
|
|||
self.log(f"Invalid x11-keyboard language specified: {language}", fg="red", level=logging.ERROR)
|
||||
return False
|
||||
|
||||
from .systemd import Boot
|
||||
|
||||
with Boot(self) as session:
|
||||
session.SysCommand(["localectl", "set-x11-keymap", '""'])
|
||||
|
||||
|
|
|
|||
|
|
@ -17,7 +17,7 @@ from .hardware import AVAILABLE_GFX_DRIVERS, has_uefi
|
|||
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
|
||||
from .profiles import Profile, list_profiles
|
||||
|
||||
|
||||
# TODO: Some inconsistencies between the selection processes.
|
||||
|
|
@ -843,28 +843,25 @@ def select_disk(dict_o_disks):
|
|||
raise DiskError('select_disk() requires a non-empty dictionary of disks to select from.')
|
||||
|
||||
|
||||
def select_profile(options):
|
||||
def select_profile():
|
||||
"""
|
||||
Asks the user to select a profile from the `options` dictionary parameter.
|
||||
Usually this is combined with :ref:`archinstall.list_profiles`.
|
||||
|
||||
:param options: A `dict` where keys are the profile name, value should be a dict containing profile information.
|
||||
:type options: dict
|
||||
Asks the user to select a profile from the available profiles.
|
||||
|
||||
:return: The name/dictionary key of the selected profile
|
||||
:rtype: str
|
||||
"""
|
||||
profiles = sorted(list(options))
|
||||
shown_profiles = sorted(list(list_profiles(filter_top_level_profiles=True)))
|
||||
actual_profiles_raw = shown_profiles + sorted([profile for profile in list_profiles() if profile not in shown_profiles])
|
||||
|
||||
if len(profiles) >= 1:
|
||||
for index, profile in enumerate(profiles):
|
||||
if len(shown_profiles) >= 1:
|
||||
for index, profile in enumerate(shown_profiles):
|
||||
print(f"{index}: {profile}")
|
||||
|
||||
print(' -- The above list is a set of pre-programmed profiles. --')
|
||||
print(' -- They might make it easier to install things like desktop environments. --')
|
||||
print(' -- (Leave blank and hit enter to skip this step and continue) --')
|
||||
|
||||
selected_profile = generic_select(profiles, 'Enter a pre-programmed profile name if you want to install one: ', options_output=False)
|
||||
selected_profile = generic_select(actual_profiles_raw, 'Enter a pre-programmed profile name if you want to install one: ', options_output=False)
|
||||
if selected_profile:
|
||||
return Profile(None, selected_profile)
|
||||
else:
|
||||
|
|
|
|||
|
|
@ -26,17 +26,113 @@ Running the guided installation
|
|||
|
||||
To install archinstall and subsequently the guided installer, simply do the following:
|
||||
|
||||
.. code::bash
|
||||
# pacman -S python-archinstall
|
||||
.. code-block:: sh
|
||||
|
||||
pacman -S python-archinstall
|
||||
|
||||
And to run it, execute archinstall as a Python module:
|
||||
|
||||
.. code::bash
|
||||
# python -m archinstall guided
|
||||
.. code-block:: sh
|
||||
|
||||
| The guided parameter is optional as it's the default behavior.
|
||||
python -m archinstall --script guided
|
||||
|
||||
| The ``--script guided`` argument is optional as it's the default behavior.
|
||||
| But this will start the process of guiding you through a installation of a quite minimal Arch Linux experience.
|
||||
|
||||
Installing directly from a config file
|
||||
--------------------------------------
|
||||
|
||||
.. note::
|
||||
Edit the following json according to your needs,
|
||||
save this as a json file, and provide the local or remote path (URL)
|
||||
|
||||
.. code-block:: json
|
||||
|
||||
{
|
||||
"audio": "pipewire",
|
||||
"bootloader": "systemd-bootctl",
|
||||
"custom-commands": [
|
||||
"cd /home/devel; git clone https://aur.archlinux.org/paru.git",
|
||||
"chown -R devel:devel /home/devel/paru",
|
||||
"usermod -aG docker devel"
|
||||
],
|
||||
"!encryption-password": "supersecret",
|
||||
"filesystem": "btrfs",
|
||||
"harddrive": {
|
||||
"path": "/dev/nvme0n1"
|
||||
},
|
||||
"hostname": "development-box",
|
||||
"kernels": [
|
||||
"linux"
|
||||
],
|
||||
"keyboard-language": "us",
|
||||
"mirror-region": {
|
||||
"Worldwide": {
|
||||
"https://mirror.rackspace.com/archlinux/$repo/os/$arch": true
|
||||
}
|
||||
},
|
||||
"nic": {
|
||||
"NetworkManager": true
|
||||
},
|
||||
"packages": ["docker", "git", "wget", "zsh"],
|
||||
"profile": "gnome",
|
||||
"services": ["docker"],
|
||||
"superusers": {
|
||||
"devel": {
|
||||
"!password": "devel"
|
||||
}
|
||||
},
|
||||
"timezone": "US/Eastern",
|
||||
"users": {}
|
||||
}
|
||||
|
||||
To run it, execute archinstall as a Python module:
|
||||
|
||||
.. code-block:: sh
|
||||
|
||||
python -m archinstall --config <local path or remote URL>
|
||||
|
||||
+----------------------+--------------------------------------------------------+----------------------------------------------------------------------------+-----------------------------------------------+
|
||||
| Key | Values/Description | Description | Required |
|
||||
| | | | |
|
||||
+======================+========================================================+============================================================================+===============================================+
|
||||
| audio | pipewire/pulseaudio | Audioserver to be installed | No |
|
||||
+----------------------+--------------------------------------------------------+----------------------------------------------------------------------------+-----------------------------------------------+
|
||||
| bootloader | systemd-bootctl/grub-install | Bootloader to be installed | Yes |
|
||||
+----------------------+--------------------------------------------------------+----------------------------------------------------------------------------+-----------------------------------------------+
|
||||
| custom-commands | [ <command1>, <command2>, ...] | Custom commands to be run post install | No |
|
||||
+----------------------+--------------------------------------------------------+----------------------------------------------------------------------------+-----------------------------------------------+
|
||||
| !encryption-password | any | Password to encrypt disk, not encrypted if password not provided | No |
|
||||
+----------------------+--------------------------------------------------------+----------------------------------------------------------------------------+-----------------------------------------------+
|
||||
| filesystem | ext4 / btrfs / fat32 etc. | Filesystem for root and home partitions | Yes |
|
||||
+----------------------+--------------------------------------------------------+----------------------------------------------------------------------------+-----------------------------------------------+
|
||||
| harddrive | { "path": <path of device> } | Path of device to be used | Yes |
|
||||
+----------------------+--------------------------------------------------------+----------------------------------------------------------------------------+-----------------------------------------------+
|
||||
| hostname | any | Hostname of machine after installation | Yes |
|
||||
+----------------------+--------------------------------------------------------+----------------------------------------------------------------------------+-----------------------------------------------+
|
||||
| kernels | [ "kernel1", "kernel2"] | List of kernels to install eg: linux, linux-lts, linux-zen etc | Atleast 1 |
|
||||
+----------------------+--------------------------------------------------------+----------------------------------------------------------------------------+-----------------------------------------------+
|
||||
| keyboard-language | 2 letter code for your keyboard language | eg: us, de etc | Yes |
|
||||
+----------------------+--------------------------------------------------------+----------------------------------------------------------------------------+-----------------------------------------------+
|
||||
| mirror-region | {"<Region Name>": { "Mirror Name": True/False}, ..} | List of regions and mirrors to use | Yes |
|
||||
+----------------------+--------------------------------------------------------+----------------------------------------------------------------------------+-----------------------------------------------+
|
||||
| nic | nic to use, Use value NetworkManager for installing it | | Yes |
|
||||
+----------------------+--------------------------------------------------------+----------------------------------------------------------------------------+-----------------------------------------------+
|
||||
| packages | [ "package1", "package2", ..] | List of packages to install post-installation | No |
|
||||
+----------------------+--------------------------------------------------------+----------------------------------------------------------------------------+-----------------------------------------------+
|
||||
| profile | Name of profile to install | profiles are present in profiles/, use the name of a profile to install it | No |
|
||||
+----------------------+--------------------------------------------------------+----------------------------------------------------------------------------+-----------------------------------------------+
|
||||
| !root-password | any | The root account password | No |
|
||||
+----------------------+--------------------------------------------------------+----------------------------------------------------------------------------+-----------------------------------------------+
|
||||
| services | [ "service1", "service2", ..] | Services to enable post-installation | No |
|
||||
+----------------------+--------------------------------------------------------+----------------------------------------------------------------------------+-----------------------------------------------+
|
||||
| superusers | { "<username>": { "!password": "<password>"}, ..} | List of superuser credentials, see config for reference | Yes, if root account password is not provided |
|
||||
+----------------------+--------------------------------------------------------+----------------------------------------------------------------------------+-----------------------------------------------+
|
||||
| timezone | Timezone to configure in installation | Timezone eg: UTC, Asia/Kolkata etc. | Yes |
|
||||
+----------------------+--------------------------------------------------------+----------------------------------------------------------------------------+-----------------------------------------------+
|
||||
| users | { "<username>": { "!password": "<password>"}, ..} | List of regular user credentials, see config for reference | Yes, can be {} |
|
||||
+----------------------+--------------------------------------------------------+----------------------------------------------------------------------------+-----------------------------------------------+
|
||||
|
||||
Description individual steps
|
||||
============================
|
||||
|
||||
|
|
@ -173,4 +269,4 @@ After which you can press :code:`Enter` can be pressed in order to start the for
|
|||
Post installation
|
||||
-----------------
|
||||
|
||||
Once the installation is complete, green text should appear saying that it's safe to `reboot`, which is also the command you use to reboot.
|
||||
Once the installation is complete, green text should appear saying that it's safe to `reboot`, which is also the command you use to reboot.
|
||||
|
|
@ -26,6 +26,7 @@
|
|||
},
|
||||
"packages": ["docker", "git", "wget", "zsh"],
|
||||
"profile": "gnome",
|
||||
"services": ["docker"],
|
||||
"superusers": {
|
||||
"devel": {
|
||||
"!password": "devel"
|
||||
|
|
|
|||
|
|
@ -12,6 +12,9 @@ from archinstall.lib.profiles import Profile
|
|||
if archinstall.arguments.get('help'):
|
||||
print("See `man archinstall` for help.")
|
||||
exit(0)
|
||||
if os.getuid() != 0:
|
||||
print("Archinstall requires root privileges to run. See --help for more.")
|
||||
exit(1)
|
||||
|
||||
# For support reasons, we'll log the disk layout pre installation to match against post-installation layout
|
||||
archinstall.log(f"Disk states before installing: {archinstall.disk_layouts()}", level=logging.DEBUG)
|
||||
|
|
@ -50,6 +53,16 @@ def ask_user_questions():
|
|||
selected_region = archinstall.arguments['mirror-region']
|
||||
archinstall.arguments['mirror-region'] = {selected_region: archinstall.list_mirrors()[selected_region]}
|
||||
|
||||
if not archinstall.arguments.get('sys-language', None) and archinstall.arguments.get('advanced', False):
|
||||
archinstall.arguments['sys-language'] = input("Enter a valid locale (language) for your OS, (Default: en_US): ").strip()
|
||||
archinstall.arguments['sys-encoding'] = input("Enter a valid system default encoding for your OS, (Default: utf-8): ").strip()
|
||||
archinstall.log("Keep in mind that if you want multiple locales, post configuration is required.", fg="yellow")
|
||||
|
||||
if not archinstall.arguments.get('sys-language', None):
|
||||
archinstall.arguments['sys-language'] = 'en_US'
|
||||
if not archinstall.arguments.get('sys-encoding', None):
|
||||
archinstall.arguments['sys-encoding'] = 'utf-8'
|
||||
|
||||
# Ask which harddrives/block-devices we will install to
|
||||
# and convert them into archinstall.BlockDevice() objects.
|
||||
if archinstall.arguments.get('harddrives', None):
|
||||
|
|
@ -103,7 +116,7 @@ def ask_user_questions():
|
|||
|
||||
# Ask for archinstall-specific profiles (such as desktop environments etc)
|
||||
if not archinstall.arguments.get('profile', None):
|
||||
archinstall.arguments['profile'] = archinstall.select_profile(archinstall.list_profiles(filter_top_level_profiles=True))
|
||||
archinstall.arguments['profile'] = archinstall.select_profile()
|
||||
else:
|
||||
archinstall.arguments['profile'] = Profile(installer=None, path=archinstall.arguments['profile'])
|
||||
|
||||
|
|
@ -162,6 +175,12 @@ def ask_user_questions():
|
|||
if not archinstall.arguments.get('timezone', None):
|
||||
archinstall.arguments['timezone'] = archinstall.ask_for_a_timezone()
|
||||
|
||||
if archinstall.arguments['timezone']:
|
||||
if not archinstall.arguments.get('ntp', False):
|
||||
archinstall.arguments['ntp'] = input("Would you like to use automatic time synchronization (NTP) with the default time servers? [Y/n]: ").strip().lower() in ('y', 'yes', '')
|
||||
if archinstall.arguments['ntp']:
|
||||
archinstall.log("Hardware time and other post-configuration steps might be required in order for NTP to work. For more information, please check the Arch wiki.", fg="yellow")
|
||||
|
||||
|
||||
def perform_filesystem_operations():
|
||||
print()
|
||||
|
|
@ -247,6 +266,7 @@ def perform_installation(mountpoint):
|
|||
if archinstall.arguments.get('mirror-region', None):
|
||||
archinstall.use_mirrors(archinstall.arguments['mirror-region']) # Set the mirrors for the live medium
|
||||
if installation.minimal_installation():
|
||||
installation.set_locale(archinstall.arguments['sys-language'], archinstall.arguments['sys-encoding'].upper())
|
||||
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
|
||||
|
|
@ -294,6 +314,9 @@ def perform_installation(mountpoint):
|
|||
if timezone := archinstall.arguments.get('timezone', None):
|
||||
installation.set_timezone(timezone)
|
||||
|
||||
if archinstall.arguments.get('ntp', False):
|
||||
installation.activate_ntp()
|
||||
|
||||
if (root_pw := archinstall.arguments.get('!root-password', None)) and len(root_pw):
|
||||
installation.user_set_pw('root', root_pw)
|
||||
|
||||
|
|
@ -307,6 +330,11 @@ def perform_installation(mountpoint):
|
|||
archinstall.log(' * Profile\'s post configuration requirements was not fulfilled.', fg='red')
|
||||
exit(1)
|
||||
|
||||
# If the user provided a list of services to be enabled, pass the list to the enable_service function.
|
||||
# Note that while it's called enable_service, it can actually take a list of services and iterate it.
|
||||
if archinstall.arguments.get('services', None):
|
||||
installation.enable_service(*archinstall.arguments['services'])
|
||||
|
||||
# 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)
|
||||
|
|
@ -345,6 +373,11 @@ else:
|
|||
else:
|
||||
archinstall.arguments['profile'] = None
|
||||
|
||||
ask_user_questions()
|
||||
if archinstall.arguments.get('mirror-region', None) is not None:
|
||||
selected_region = archinstall.arguments.get('mirror-region', None)
|
||||
archinstall.arguments['mirror-region'] = {selected_region: archinstall.list_mirrors()[selected_region]}
|
||||
archinstall.arguments['sys-language'] = archinstall.arguments.get('sys-language', 'en_US')
|
||||
archinstall.arguments['sys-encoding'] = archinstall.arguments.get('sys-encoding', 'utf-8')
|
||||
|
||||
perform_filesystem_operations()
|
||||
perform_installation(archinstall.arguments.get('target-mountpoint', None))
|
||||
Loading…
Reference in New Issue