Merge pull request #57 from vamega/fixup

Fix minor issues like typos and code style violations.
This commit is contained in:
Anton Hvornum 2020-10-20 20:39:46 +02:00 committed by GitHub
commit 2fc51d540a
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
28 changed files with 164 additions and 116 deletions

View File

@ -17,7 +17,7 @@ Or simply `git clone` the repo as it has no external dependencies *(but there ar
Or run the pre-compiled binary attached in every release as `archinstall-v[ver].tar.gz`. Or run the pre-compiled binary attached in every release as `archinstall-v[ver].tar.gz`.
There's also `PKGBUILD`'s for all the above scenarios. There's also `PKGBUILD`'s for all the above scenarios.
And they're also availale as Arch Linux packages over at the unofficial mirror [https://archlinux.life](https://archlinux.life/). And they're also available as Arch Linux packages over at the unofficial mirror [https://archlinux.life](https://archlinux.life/).
## Running the [guided](examples/guided.py) installer ## Running the [guided](examples/guided.py) installer

View File

@ -11,4 +11,4 @@ from .lib.locale_helpers import *
from .lib.services import * from .lib.services import *
from .lib.packages import * from .lib.packages import *
from .lib.output import * from .lib.output import *
from .lib.storage import * from .lib.storage import *

View File

@ -21,7 +21,7 @@ def find_examples():
def run_as_a_module(): def run_as_a_module():
""" """
Ssince we're running this as a 'python -m archinstall' module OR Since we're running this as a 'python -m archinstall' module OR
a nuitka3 compiled version of the project. a nuitka3 compiled version of the project.
This function and the file __main__ acts as a entry point. This function and the file __main__ acts as a entry point.
""" """
@ -30,14 +30,17 @@ def run_as_a_module():
profile = sys.argv[1] profile = sys.argv[1]
library = find_examples() library = find_examples()
if not f'{profile}.py' in library: if f'{profile}.py' not in library:
raise ProfileNotFound(f'Could not locate {profile}.py among the example files.') raise ProfileNotFound(f'Could not locate {profile}.py among the example files.')
# Import and execute the chosen `<profile>.py`: # Import and execute the chosen `<profile>.py`:
spec = importlib.util.spec_from_file_location(library[f'{profile}.py'], library[f'{profile}.py']) spec = importlib.util.spec_from_file_location(
library[f"{profile}.py"],
library[f"{profile}.py"]
)
imported_path = importlib.util.module_from_spec(spec) imported_path = importlib.util.module_from_spec(spec)
spec.loader.exec_module(imported_path) spec.loader.exec_module(imported_path)
sys.modules[library[f'{profile}.py']] = imported_path sys.modules[library[f'{profile}.py']] = imported_path
if __name__ == '__main__': if __name__ == '__main__':
run_as_a_module() run_as_a_module()

View File

@ -1,6 +1,6 @@
import glob, re, os, json import glob, re, os, json
from collections import OrderedDict from collections import OrderedDict
from .exceptions import * from .exceptions import DiskError
from .general import * from .general import *
ROOT_DIR_PATTERN = re.compile('^.*?/devices') ROOT_DIR_PATTERN = re.compile('^.*?/devices')
@ -21,7 +21,7 @@ class BlockDevice():
return f"BlockDevice({self.device})" return f"BlockDevice({self.device})"
def __getitem__(self, key, *args, **kwargs): def __getitem__(self, key, *args, **kwargs):
if not key in self.info: if key not in self.info:
raise KeyError(f'{self} does not contain information: "{key}"') raise KeyError(f'{self} does not contain information: "{key}"')
return self.info[key] return self.info[key]
@ -37,9 +37,9 @@ class BlockDevice():
def __dump__(self): def __dump__(self):
return { return {
'path' : self.path, 'path': self.path,
'info' : self.info, 'info': self.info,
'partition_cache' : self.part_cache 'partition_cache': self.part_cache
} }
@property @property
@ -50,7 +50,8 @@ class BlockDevice():
If it's a ATA-drive 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 And if it's a crypto-device it returns the parent device
""" """
if not 'type' in self.info: raise DiskError(f'Could not locate backplane info for "{self.path}"') if "type" not in self.info:
raise DiskError(f'Could not locate backplane info for "{self.path}"')
if self.info['type'] == 'loop': if self.info['type'] == 'loop':
for drive in json.loads(b''.join(sys_command(f'losetup --json', hide_from_log=True)).decode('UTF_8'))['loopdevices']: for drive in json.loads(b''.join(sys_command(f'losetup --json', hide_from_log=True)).decode('UTF_8'))['loopdevices']:
@ -60,7 +61,8 @@ class BlockDevice():
elif self.info['type'] == 'disk': elif self.info['type'] == 'disk':
return self.path return self.path
elif self.info['type'] == 'crypt': elif self.info['type'] == 'crypt':
if not 'pkname' in self.info: raise DiskError(f'A crypt device ({self.path}) without a parent kernel device name.') if 'pkname' not in self.info:
raise DiskError(f'A crypt device ({self.path}) without a parent kernel device name.')
return f"/dev/{self.info['pkname']}" return f"/dev/{self.info['pkname']}"
# if not stat.S_ISBLK(os.stat(full_path).st_mode): # if not stat.S_ISBLK(os.stat(full_path).st_mode):
@ -97,7 +99,8 @@ class BlockDevice():
class Partition(): class Partition():
def __init__(self, path, part_id=None, size=-1, filesystem=None, mountpoint=None, encrypted=False): def __init__(self, path, part_id=None, size=-1, filesystem=None, mountpoint=None, encrypted=False):
if not part_id: part_id = os.path.basename(path) if not part_id:
part_id = os.path.basename(path)
self.path = path self.path = path
self.part_id = part_id self.part_id = part_id
self.mountpoint = mountpoint self.mountpoint = mountpoint
@ -115,7 +118,7 @@ class Partition():
log(f'Formatting {self} -> {filesystem}') log(f'Formatting {self} -> {filesystem}')
if filesystem == 'btrfs': if filesystem == 'btrfs':
o = b''.join(sys_command(f'/usr/bin/mkfs.btrfs -f {self.path}')) o = b''.join(sys_command(f'/usr/bin/mkfs.btrfs -f {self.path}'))
if not b'UUID' in o: if b'UUID' not in o:
raise DiskError(f'Could not format {self.path} with {filesystem} because: {o}') raise DiskError(f'Could not format {self.path} with {filesystem} because: {o}')
self.filesystem = 'btrfs' self.filesystem = 'btrfs'
elif filesystem == 'fat32': elif filesystem == 'fat32':
@ -244,11 +247,11 @@ def device_state(name, *args, **kwargs):
# lsblk --json -l -n -o path # lsblk --json -l -n -o path
def all_disks(*args, **kwargs): def all_disks(*args, **kwargs):
if not 'partitions' in kwargs: kwargs['partitions'] = False kwargs.setdefault("partitions", False)
drives = OrderedDict() drives = OrderedDict()
#for drive in json.loads(sys_command(f'losetup --json', *args, **lkwargs, hide_from_log=True)).decode('UTF_8')['loopdevices']: #for drive in json.loads(sys_command(f'losetup --json', *args, **lkwargs, hide_from_log=True)).decode('UTF_8')['loopdevices']:
for drive in json.loads(b''.join(sys_command(f'lsblk --json -l -n -o path,size,type,mountpoint,label,pkname', *args, **kwargs, hide_from_log=True)).decode('UTF_8'))['blockdevices']: for drive in json.loads(b''.join(sys_command(f'lsblk --json -l -n -o path,size,type,mountpoint,label,pkname', *args, **kwargs, hide_from_log=True)).decode('UTF_8'))['blockdevices']:
if not kwargs['partitions'] and drive['type'] == 'part': continue if not kwargs['partitions'] and drive['type'] == 'part': continue
drives[drive['path']] = BlockDevice(drive['path'], drive) drives[drive['path']] = BlockDevice(drive['path'], drive)
return drives return drives

View File

@ -73,9 +73,10 @@ class sys_command():#Thread):
Stolen from archinstall_gui Stolen from archinstall_gui
""" """
def __init__(self, cmd, callback=None, start_callback=None, *args, **kwargs): def __init__(self, cmd, callback=None, start_callback=None, *args, **kwargs):
if not 'worker_id' in kwargs: kwargs['worker_id'] = gen_uid() kwargs.setdefault("worker_id", gen_uid())
if not 'emulate' in kwargs: kwargs['emulate'] = False kwargs.setdefault("emulate", False)
if not 'surpress_errors' in kwargs: kwargs['surpress_errors'] = False kwargs.setdefault("suppress_errors", False)
if kwargs['emulate']: if kwargs['emulate']:
log(f"Starting command '{cmd}' in emulation mode.") log(f"Starting command '{cmd}' in emulation mode.")
self.raw_cmd = cmd self.raw_cmd = cmd
@ -85,7 +86,8 @@ class sys_command():#Thread):
raise ValueError(f'Incorrect string to split: {cmd}\n{e}') raise ValueError(f'Incorrect string to split: {cmd}\n{e}')
self.args = args self.args = args
self.kwargs = kwargs self.kwargs = kwargs
if not 'worker' in self.kwargs: self.kwargs['worker'] = None
self.kwargs.setdefault("worker", None)
self.callback = callback self.callback = callback
self.pid = None self.pid = None
self.exit_code = None self.exit_code = None
@ -100,9 +102,9 @@ class sys_command():#Thread):
self.exec_dir = f'{self.cwd}/{os.path.basename(self.cmd[0])}_workingdir' self.exec_dir = f'{self.cwd}/{os.path.basename(self.cmd[0])}_workingdir'
if not self.cmd[0][0] == '/': if not self.cmd[0][0] == '/':
# "which" doesn't work as it's a builin to bash. # "which" doesn't work as it's a builtin to bash.
# It used to work, but for whatever reason it doesn't anymore. So back to square one.. # It used to work, but for whatever reason it doesn't anymore. So back to square one..
#log('Worker command is not executed with absolute path, trying to find: {}'.format(self.cmd[0]), origin='spawn', level=5) #log('Worker command is not executed with absolute path, trying to find: {}'.format(self.cmd[0]), origin='spawn', level=5)
#log('This is the binary {} for {}'.format(o.decode('UTF-8'), self.cmd[0]), origin='spawn', level=5) #log('This is the binary {} for {}'.format(o.decode('UTF-8'), self.cmd[0]), origin='spawn', level=5)
self.cmd[0] = locate_binary(self.cmd[0]) self.cmd[0] = locate_binary(self.cmd[0])
@ -110,7 +112,8 @@ class sys_command():#Thread):
if not os.path.isdir(self.exec_dir): if not os.path.isdir(self.exec_dir):
os.makedirs(self.exec_dir) os.makedirs(self.exec_dir)
if start_callback: start_callback(self, *args, **kwargs) if start_callback:
start_callback(self, *args, **kwargs)
self.run() self.run()
def __iter__(self, *args, **kwargs): def __iter__(self, *args, **kwargs):
@ -125,14 +128,14 @@ class sys_command():#Thread):
def dump(self): def dump(self):
return { return {
'status' : self.status, 'status': self.status,
'worker_id' : self.worker_id, 'worker_id': self.worker_id,
'worker_result' : self.trace_log.decode('UTF-8'), 'worker_result': self.trace_log.decode('UTF-8'),
'started' : self.started, 'started': self.started,
'ended' : self.ended, 'ended': self.ended,
'started_pprint' : '{}-{}-{} {}:{}:{}'.format(*time.localtime(self.started)), 'started_pprint': '{}-{}-{} {}:{}:{}'.format(*time.localtime(self.started)),
'ended_pprint' : '{}-{}-{} {}:{}:{}'.format(*time.localtime(self.ended)) if self.ended else None, 'ended_pprint': '{}-{}-{} {}:{}:{}'.format(*time.localtime(self.ended)) if self.ended else None,
'exit_code' : self.exit_code 'exit_code': self.exit_code
} }
def run(self): def run(self):
@ -238,7 +241,7 @@ class sys_command():#Thread):
if 'ignore_errors' in self.kwargs: if 'ignore_errors' in self.kwargs:
self.exit_code = 0 self.exit_code = 0
if self.exit_code != 0 and not self.kwargs['surpress_errors']: if self.exit_code != 0 and not self.kwargs['suppress_errors']:
log(f"'{self.raw_cmd}' did not exit gracefully, exit code {self.exit_code}.") log(f"'{self.raw_cmd}' did not exit gracefully, exit code {self.exit_code}.")
log(self.trace_log.decode('UTF-8')) log(self.trace_log.decode('UTF-8'))
raise SysCallError(f"'{self.raw_cmd}' did not exit gracefully, exit code {self.exit_code}.\n{self.trace_log.decode('UTF-8')}") raise SysCallError(f"'{self.raw_cmd}' did not exit gracefully, exit code {self.exit_code}.\n{self.trace_log.decode('UTF-8')}")
@ -247,11 +250,12 @@ class sys_command():#Thread):
with open(f'{self.cwd}/trace.log', 'wb') as fh: with open(f'{self.cwd}/trace.log', 'wb') as fh:
fh.write(self.trace_log) fh.write(self.trace_log)
def prerequisit_check():
if not os.path.isdir('/sys/firmware/efi'): def prerequisite_check():
raise RequirementError('Archinstall only supports machines in UEFI mode.') if not os.path.isdir("/sys/firmware/efi"):
raise RequirementError("Archinstall only supports machines in UEFI mode.")
return True return True
def reboot(): def reboot():
o = b''.join(sys_command(("/usr/bin/reboot"))) o = b''.join(sys_command("/usr/bin/reboot"))

View File

@ -137,12 +137,14 @@ class Installer():
if self.partition.filesystem == 'btrfs': if self.partition.filesystem == 'btrfs':
#if self.partition.encrypted: #if self.partition.encrypted:
self.base_packages.append('btrfs-progs') self.base_packages.append('btrfs-progs')
self.pacstrap(self.base_packages) self.pacstrap(self.base_packages)
self.genfstab() self.genfstab()
with open(f'{self.mountpoint}/etc/fstab', 'a') as fstab: with open(f"{self.mountpoint}/etc/fstab", "a") as fstab:
fstab.write('\ntmpfs /tmp tmpfs defaults,noatime,mode=1777 0 0\n') # Redundant \n at the start? who knoes? fstab.write(
"\ntmpfs /tmp tmpfs defaults,noatime,mode=1777 0 0\n"
) # Redundant \n at the start? who knows?
## TODO: Support locale and timezone ## TODO: Support locale and timezone
#os.remove(f'{self.mountpoint}/etc/localtime') #os.remove(f'{self.mountpoint}/etc/localtime')
@ -182,7 +184,7 @@ class Installer():
entry.write('initrd /initramfs-linux.img\n') entry.write('initrd /initramfs-linux.img\n')
## blkid doesn't trigger on loopback devices really well, ## blkid doesn't trigger on loopback devices really well,
## so we'll use the old manual method until we get that sorted out. ## so we'll use the old manual method until we get that sorted out.
if self.partition.encrypted: if self.partition.encrypted:
for root, folders, uids in os.walk('/dev/disk/by-uuid'): for root, folders, uids in os.walk('/dev/disk/by-uuid'):
@ -191,7 +193,7 @@ class Installer():
if not os.path.basename(real_path) == os.path.basename(self.partition.real_device): continue if not os.path.basename(real_path) == os.path.basename(self.partition.real_device): continue
entry.write(f'options cryptdevice=UUID={uid}:luksdev root=/dev/mapper/luksdev rw intel_pstate=no_hwp\n') entry.write(f'options cryptdevice=UUID={uid}:luksdev root=/dev/mapper/luksdev rw intel_pstate=no_hwp\n')
self.helper_flags['bootloader'] = True self.helper_flags['bootloader'] = True
return True return True
break break
@ -202,7 +204,7 @@ class Installer():
if not os.path.basename(real_path) == os.path.basename(self.partition.path): continue if not os.path.basename(real_path) == os.path.basename(self.partition.path): continue
entry.write(f'options root=PARTUUID={uid} rw intel_pstate=no_hwp\n') entry.write(f'options root=PARTUUID={uid} rw intel_pstate=no_hwp\n')
self.helper_flags['bootloader'] = True self.helper_flags['bootloader'] = True
return True return True
break break
@ -228,7 +230,7 @@ class Installer():
o = b''.join(sys_command(f'/usr/bin/arch-chroot {self.mountpoint} useradd -m -G wheel {user}')) o = b''.join(sys_command(f'/usr/bin/arch-chroot {self.mountpoint} useradd -m -G wheel {user}'))
if password: if password:
self.user_set_pw(user, password) self.user_set_pw(user, password)
if groups: if groups:
for group in groups: for group in groups:
o = b''.join(sys_command(f'/usr/bin/arch-chroot {self.mountpoint} gpasswd -a {user} {group}')) o = b''.join(sys_command(f'/usr/bin/arch-chroot {self.mountpoint} gpasswd -a {user} {group}'))

View File

@ -23,14 +23,15 @@ class luks2():
def encrypt(self, partition, password, key_size=512, hash_type='sha512', iter_time=10000, key_file=None): def encrypt(self, partition, password, key_size=512, hash_type='sha512', iter_time=10000, key_file=None):
log(f'Encrypting {partition}') log(f'Encrypting {partition}')
if not key_file: key_file = f'/tmp/{os.path.basename(self.partition.path)}.disk_pw' #TODO: Make disk-pw-file randomly unique? if not key_file:
key_file = f"/tmp/{os.path.basename(self.partition.path)}.disk_pw" # TODO: Make disk-pw-file randomly unique?
if type(password) != bytes: password = bytes(password, 'UTF-8') if type(password) != bytes: password = bytes(password, 'UTF-8')
with open(key_file, 'wb') as fh: with open(key_file, 'wb') as fh:
fh.write(password) fh.write(password)
o = b''.join(sys_command(f'/usr/bin/cryptsetup -q -v --type luks2 --pbkdf argon2i --hash {hash_type} --key-size {key_size} --iter-time {iter_time} --key-file {os.path.abspath(key_file)} --use-urandom luksFormat {partition.path}')) o = b''.join(sys_command(f'/usr/bin/cryptsetup -q -v --type luks2 --pbkdf argon2i --hash {hash_type} --key-size {key_size} --iter-time {iter_time} --key-file {os.path.abspath(key_file)} --use-urandom luksFormat {partition.path}'))
if not b'Command successful.' in o: if b'Command successful.' not in o:
raise DiskError(f'Could not encrypt volume "{partition.path}": {o}') raise DiskError(f'Could not encrypt volume "{partition.path}": {o}')
return key_file return key_file
@ -43,7 +44,8 @@ class luks2():
:param mountpoint: The name without absolute path, for instance "luksdev" will point to /dev/mapper/luksdev :param mountpoint: The name without absolute path, for instance "luksdev" will point to /dev/mapper/luksdev
:type mountpoint: str :type mountpoint: str
""" """
if '/' in mountpoint: os.path.basename(mountpoint) # TODO: Raise exception instead? if '/' in mountpoint:
os.path.basename(mountpoint) # TODO: Raise exception instead?
sys_command(f'/usr/bin/cryptsetup open {partition.path} {mountpoint} --key-file {os.path.abspath(key_file)} --type luks2') sys_command(f'/usr/bin/cryptsetup open {partition.path} {mountpoint} --key-file {os.path.abspath(key_file)} --type luks2')
if os.path.islink(f'/dev/mapper/{mountpoint}'): if os.path.islink(f'/dev/mapper/{mountpoint}'):
return Partition(f'/dev/mapper/{mountpoint}', encrypted=True) return Partition(f'/dev/mapper/{mountpoint}', encrypted=True)

View File

@ -78,16 +78,16 @@ def list_mirrors():
region = 'Unknown region' region = 'Unknown region'
for line in response.readlines(): for line in response.readlines():
if len(line.strip()) == 0: continue if len(line.strip()) == 0:
continue
line = line.decode('UTF-8').strip('\n').strip('\r') line = line.decode('UTF-8').strip('\n').strip('\r')
if line[:3] == '## ': if line[:3] == '## ':
region = line[3:] region = line[3:]
elif line[:10] == '#Server = ': elif line[:10] == '#Server = ':
if not region in regions: regions.setdefault(region, {})
regions[region] = {}
url = line[1:].lstrip('Server = ') url = line.lstrip('#Server = ')
regions[region][url] = True regions[region][url] = True
return regions return regions

View File

@ -3,7 +3,6 @@ import socket
import struct import struct
from collections import OrderedDict from collections import OrderedDict
from .exceptions import *
def getHwAddr(ifname): def getHwAddr(ifname):
s = socket.socket(socket.AF_INET, socket.SOCK_DGRAM) s = socket.socket(socket.AF_INET, socket.SOCK_DGRAM)
@ -13,7 +12,8 @@ def getHwAddr(ifname):
def list_interfaces(skip_loopback=True): def list_interfaces(skip_loopback=True):
interfaces = OrderedDict() interfaces = OrderedDict()
for index, iface in socket.if_nameindex(): for index, iface in socket.if_nameindex():
if skip_loopback and iface == 'lo': continue if skip_loopback and iface == "lo":
continue
mac = getHwAddr(iface).replace(':', '-') mac = getHwAddr(iface).replace(':', '-')
interfaces[mac] = iface interfaces[mac] = iface

View File

@ -11,7 +11,7 @@ def find_package(name):
""" """
ssl_context = ssl.create_default_context() ssl_context = ssl.create_default_context()
ssl_context.check_hostname = False ssl_context.check_hostname = False
ssl_context.verify_mode=ssl.CERT_NONE ssl_context.verify_mode = ssl.CERT_NONE
response = urllib.request.urlopen(BASE_URL.format(package=name), context=ssl_context) response = urllib.request.urlopen(BASE_URL.format(package=name), context=ssl_context)
data = response.read().decode('UTF-8') data = response.read().decode('UTF-8')
return json.loads(data) return json.loads(data)

View File

@ -106,7 +106,7 @@ class Profile():
# To avoid profiles importing the wrong 'archinstall', # To avoid profiles importing the wrong 'archinstall',
# we need to ensure that this current archinstall is in sys.path # we need to ensure that this current archinstall is in sys.path
archinstall_path = os.path.abspath(f'{os.path.dirname(__file__)}/../../') archinstall_path = os.path.abspath(f'{os.path.dirname(__file__)}/../../')
if not archinstall_path in sys.path: if archinstall_path not in sys.path:
sys.path.insert(0, archinstall_path) sys.path.insert(0, archinstall_path)
instructions = self.load_instructions() instructions = self.load_instructions()

View File

@ -3,11 +3,10 @@ import os
from .exceptions import * from .exceptions import *
from .general import * from .general import *
def service_state(service_name :str): def service_state(service_name: str):
if os.path.splitext(service_name)[1] != '.service': if os.path.splitext(service_name)[1] != '.service':
service_name += '.service' # Just to be safe service_name += '.service' # Just to be safe
state = b''.join(sys_command(f'systemctl show -p SubState --value {service_name}')) state = b''.join(sys_command(f'systemctl show -p SubState --value {service_name}'))
return state.strip().decode('UTF-8') return state.strip().decode('UTF-8')

0
archinstall/lib/tts.py Normal file
View File

View File

@ -170,7 +170,7 @@ def select_mirror_regions(mirrors, show_top_mirrors=True):
:rtype: dict :rtype: dict
""" """
# TODO: Support multiple options and country ycodes, SE,UK for instance. # TODO: Support multiple options and country codes, SE,UK for instance.
regions = sorted(list(mirrors.keys())) regions = sorted(list(mirrors.keys()))
selected_mirrors = {} selected_mirrors = {}
@ -205,7 +205,7 @@ def select_mirror_regions(mirrors, show_top_mirrors=True):
selected_mirrors[selected_mirror] = mirrors[selected_mirror] selected_mirrors[selected_mirror] = mirrors[selected_mirror]
else: else:
RequirementError("Selected region does not exist.") RequirementError("Selected region does not exist.")
return selected_mirrors return selected_mirrors
raise RequirementError("Selecting mirror region require a least one region to be given as an option.") raise RequirementError("Selecting mirror region require a least one region to be given as an option.")

View File

@ -4,7 +4,7 @@ archinstall.Application
======================= =======================
This class enables access to pre-programmed application configurations. This class enables access to pre-programmed application configurations.
This is not to be confused with :ref:`archinstall.Profile` which is for pre-prgrammed profiles for a wider set of installation sets. This is not to be confused with :ref:`archinstall.Profile` which is for pre-programmed profiles for a wider set of installation sets.
.. autofunction:: archinstall.Application .. autofunction:: archinstall.Application

View File

@ -4,7 +4,7 @@ archinstall.Profile
=================== ===================
This class enables access to pre-programmed profiles. This class enables access to pre-programmed profiles.
This is not to be confused with :ref:`archinstall.Application` which is for pre-prgrammed application profiles. This is not to be confused with :ref:`archinstall.Application` which is for pre-programmed application profiles.
Profiles in general is a set or group of installation steps. Profiles in general is a set or group of installation steps.
Where as applications are a specific set of instructions for a very specific application. Where as applications are a specific set of instructions for a very specific application.

View File

@ -1,17 +1,18 @@
import sys, os import os
import re
import sys
sys.path.insert(0, os.path.abspath('..')) sys.path.insert(0, os.path.abspath('..'))
import re
def process_docstring(app, what, name, obj, options, lines): def process_docstring(app, what, name, obj, options, lines):
spaces_pat = re.compile(r"( {8})") spaces_pat = re.compile(r"( {8})")
ll = [] ll = []
for l in lines: for l in lines:
ll.append(spaces_pat.sub(" ",l)) ll.append(spaces_pat.sub(" ", l))
lines[:] = ll lines[:] = ll
def setup(app): def setup(app):
app.connect('autodoc-process-docstring', process_docstring) app.connect('autodoc-process-docstring', process_docstring)
# Configuration file for the Sphinx documentation builder. # Configuration file for the Sphinx documentation builder.
# #
@ -110,8 +111,10 @@ htmlhelp_basename = 'slimhttpdoc'
# One entry per manual page. List of tuples # One entry per manual page. List of tuples
# (source start file, name, description, authors, manual section). # (source start file, name, description, authors, manual section).
man_pages = [ man_pages = [
('index', 'archinstall', u'archinstall Documentation', (
[u'Anton Hvornum'], 1) "index", "archinstall", u"archinstall Documentation",
[u"Anton Hvornum"], 1
)
] ]
# If true, show URL addresses after external links. # If true, show URL addresses after external links.
@ -124,6 +127,8 @@ man_pages = [
# (source start file, target name, title, author, # (source start file, target name, title, author,
# dir menu entry, description, category) # dir menu entry, description, category)
texinfo_documents = [ texinfo_documents = [
('index', 'archinstall', u'archinstall Documentation', (
u'Anton Hvornum', 'archinstall', 'Simple and minimal HTTP server.'), "index", "archinstall", u"archinstall Documentation",
u"Anton Hvornum", "archinstall", "Simple and minimal HTTP server."
),
] ]

View File

@ -8,7 +8,7 @@ The way the library is invoked in module mode is limited to executing scripts un
It's there for important to place any script or profile you wish to invoke in the examples folder prior to building and installing. It's there for important to place any script or profile you wish to invoke in the examples folder prior to building and installing.
Pre-requisits Pre-requisites
------------- -------------
We'll assume you've followed the `installing.python.manual`_ method. We'll assume you've followed the `installing.python.manual`_ method.

View File

@ -3,14 +3,14 @@
Guided installation Guided installation
=================== ===================
This is the installer you'll encounter on the *(currently)* inofficial Arch Linux Archinstall ISO found on `archlinux.life <https://archlinux.life>`_. This is the installer you'll encounter on the *(currently)* unofficial Arch Linux Archinstall ISO found on `archlinux.life <https://archlinux.life>`_.
You'll obviously need a physical machine or a virtual machine and have a basic understanding of how ISO-files work, where and how to mount them in order to boot the installer. You'll obviously need a physical machine or a virtual machine and have a basic understanding of how ISO-files work, where and how to mount them in order to boot the installer.
It runs you through a set of questions in order to determine what the system should look like. Then the guided installer performs the required installation steps for you. Some additional steps might show up depending on your chosen input at some of the steps - those steps should be self explanatory and won't be covered here. It runs you through a set of questions in order to determine what the system should look like. Then the guided installer performs the required installation steps for you. Some additional steps might show up depending on your chosen input at some of the steps - those steps should be self explanatory and won't be covered here.
.. note:: .. note::
There are some limitations with the installer, such as that it will not configure WiFi during the installation proceedure. And it will not perform a post-installation network configuration either. So you need to read up on `Arch Linux networking <https://wiki.archlinux.org/index.php/Network_configuration>`_ to get that to work. There are some limitations with the installer, such as that it will not configure WiFi during the installation procedure. And it will not perform a post-installation network configuration either. So you need to read up on `Arch Linux networking <https://wiki.archlinux.org/index.php/Network_configuration>`_ to get that to work.
Features Features
-------- --------
@ -18,7 +18,7 @@ Features
The guided installer currently supports: The guided installer currently supports:
* *(optional)* Setting up disk encryption * *(optional)* Setting up disk encryption
* *(optional)* Installing some simpel desktop environments * *(optional)* Installing some simple desktop environments
* Choosing between a super-user or root based user setup * Choosing between a super-user or root based user setup
Installation steps Installation steps

View File

@ -3,7 +3,7 @@
Python library Python library
============== ==============
Archinstall shipps on `PyPi <https://pypi.org/>`_ as `archinstall <pypi.org/project/archinstall/>`_. Archinstall ships on `PyPi <https://pypi.org/>`_ as `archinstall <pypi.org/project/archinstall/>`_.
But the library can be installed manually as well. But the library can be installed manually as well.
.. warning:: .. warning::

View File

@ -9,10 +9,12 @@ SIG_TRIGGER = False
def kill_handler(sig, frame): def kill_handler(sig, frame):
print() print()
exit(0) exit(0)
def sig_handler(sig, frame): def sig_handler(sig, frame):
global SIG_TRIGGER global SIG_TRIGGER
SIG_TRIGGER = True SIG_TRIGGER = True
signal.signal(signal.SIGINT, kill_handler) signal.signal(signal.SIGINT, kill_handler)
original_sigint_handler = signal.getsignal(signal.SIGINT) original_sigint_handler = signal.getsignal(signal.SIGINT)
signal.signal(signal.SIGINT, sig_handler) signal.signal(signal.SIGINT, sig_handler)
@ -54,8 +56,8 @@ def perform_installation(device, boot_partition, language, mirrors):
installation.user_set_pw('root', root_pw) installation.user_set_pw('root', root_pw)
# Unmount and close previous runs (in case the installer is restarted) # Unmount and close previous runs (in case the installer is restarted)
archinstall.sys_command(f'umount -R /mnt', surpress_errors=True) archinstall.sys_command(f'umount -R /mnt', suppress_errors=True)
archinstall.sys_command(f'cryptsetup close /dev/mapper/luksloop', surpress_errors=True) archinstall.sys_command(f'cryptsetup close /dev/mapper/luksloop', suppress_errors=True)
""" """
First, we'll ask the user for a bunch of user input. First, we'll ask the user for a bunch of user input.
@ -86,7 +88,8 @@ archinstall.storage['_guided']['harddrive'] = harddrive
# Ask for a hostname # Ask for a hostname
hostname = input('Desired hostname for the installation: ') hostname = input('Desired hostname for the installation: ')
if len(hostname) == 0: hostname = 'ArchInstall' if len(hostname) == 0:
hostname = 'ArchInstall'
archinstall.storage['_guided']['hostname'] = hostname archinstall.storage['_guided']['hostname'] = hostname
# Ask for a root password (optional, but triggers requirement for super-user if skipped) # Ask for a root password (optional, but triggers requirement for super-user if skipped)
@ -111,7 +114,8 @@ while 1:
continue continue
break break
if 'users' not in archinstall.storage['_guided']: archinstall.storage['_guided']['users'] = [] if 'users' not in archinstall.storage['_guided']:
archinstall.storage['_guided']['users'] = []
archinstall.storage['_guided']['users'].append(new_user) archinstall.storage['_guided']['users'].append(new_user)
new_user_passwd = getpass.getpass(prompt=f'Password for user {new_user}: ') new_user_passwd = getpass.getpass(prompt=f'Password for user {new_user}: ')
@ -129,13 +133,17 @@ while 1:
if profile: if profile:
archinstall.storage['_guided']['profile'] = profile archinstall.storage['_guided']['profile'] = profile
if type(profile) != str: # Got a imported profile if type(profile) != str: # Got a imported profile
archinstall.storage['_guided']['profile'] = profile[0] # The second return is a module, and not a handle/object. archinstall.storage['_guided']['profile'] = profile[0] # The second return is a module, and not a handle/object.
if not profile[1]._prep_function(): if not profile[1]._prep_function():
archinstall.log(' * Profile\'s preperation requirements was not fulfilled.', bg='black', fg='red') archinstall.log(
' * Profile\'s preparation requirements was not fulfilled.',
bg='black',
fg='red'
)
continue continue
profile = profile[0]._path # Once the prep is done, replace the selected profile with the profile name ("path") given from select_profile() profile = profile[0]._path # Once the prep is done, replace the selected profile with the profile name ("path") given from select_profile()
break break
else: else:
break break
@ -207,7 +215,7 @@ with archinstall.Filesystem(harddrive, archinstall.GPT) as fs:
# unlocks the drive so that it can be used as a normal block-device within archinstall. # unlocks the drive so that it can be used as a normal block-device within archinstall.
with archinstall.luks2(harddrive.partition[1], 'luksloop', disk_password) as unlocked_device: with archinstall.luks2(harddrive.partition[1], 'luksloop', disk_password) as unlocked_device:
unlocked_device.format('btrfs') unlocked_device.format('btrfs')
perform_installation(unlocked_device, harddrive.partition[0], keyboard_language, mirror_regions) perform_installation(unlocked_device, harddrive.partition[0], keyboard_language, mirror_regions)
else: else:
harddrive.partition[1].format('ext4') harddrive.partition[1].format('ext4')

View File

@ -1,8 +1,8 @@
import archinstall, getpass import archinstall, getpass
# Unmount and close previous runs # Unmount and close previous runs
archinstall.sys_command(f'umount -R /mnt', surpress_errors=True) archinstall.sys_command(f'umount -R /mnt', suppress_errors=True)
archinstall.sys_command(f'cryptsetup close /dev/mapper/luksloop', surpress_errors=True) archinstall.sys_command(f'cryptsetup close /dev/mapper/luksloop', suppress_errors=True)
# Select a harddrive and a disk password # Select a harddrive and a disk password
harddrive = archinstall.select_disk(archinstall.all_disks()) harddrive = archinstall.select_disk(archinstall.all_disks())

View File

@ -4,8 +4,8 @@ import urllib.request
import git import git
# Unmount and close previous runs (Mainly only used for re-runs, but won't hurt.) # Unmount and close previous runs (Mainly only used for re-runs, but won't hurt.)
archinstall.sys_command(f'umount -R /mnt', surpress_errors=True) archinstall.sys_command(f'umount -R /mnt', suppress_errors=True)
archinstall.sys_command(f'cryptsetup close /dev/mapper/luksloop', surpress_errors=True) archinstall.sys_command(f'cryptsetup close /dev/mapper/luksloop', suppress_errors=True)
# Select a harddrive and a disk password # Select a harddrive and a disk password
harddrive = archinstall.all_disks()['/dev/sda'] harddrive = archinstall.all_disks()['/dev/sda']
@ -22,7 +22,11 @@ with archinstall.Filesystem(harddrive, archinstall.GPT) as fs:
with archinstall.luks2(harddrive.partition[1], 'luksloop', disk_password) as unlocked_device: with archinstall.luks2(harddrive.partition[1], 'luksloop', disk_password) as unlocked_device:
unlocked_device.format('btrfs') unlocked_device.format('btrfs')
with archinstall.Installer(unlocked_device, boot_partition=harddrive.partition[0], hostname='testmachine') as installation: with archinstall.Installer(
unlocked_device,
boot_partition=harddrive.partition[0],
hostname="testmachine"
) as installation:
if installation.minimal_installation(): if installation.minimal_installation():
installation.add_bootloader() installation.add_bootloader()
@ -37,7 +41,12 @@ with archinstall.Filesystem(harddrive, archinstall.GPT) as fs:
print(f'Submitting {commit}: success') print(f'Submitting {commit}: success')
conditions = {"project" : "archinstall", "profile" : "52-54-00-12-34-56", "status" : "success", "commit" : commit} conditions = {
"project": "archinstall",
"profile": "52-54-00-12-34-56",
"status": "success",
"commit": commit
}
req = urllib.request.Request("https://api.archlinux.life/build/success", req = urllib.request.Request("https://api.archlinux.life/build/success",
data=json.dumps(conditions).encode('utf8'), data=json.dumps(conditions).encode('utf8'),
headers={'content-type': 'application/json'}) headers={'content-type': 'application/json'})

View File

@ -1,14 +1,19 @@
import archinstall import archinstall
installation.add_additional_packages("awesome xorg-xrandr xterm feh slock terminus-font-otb gnu-free-fonts ttf-liberation xsel") installation.add_additional_packages(
"awesome xorg-xrandr xterm feh slock terminus-font-otb gnu-free-fonts ttf-liberation xsel"
)
with open(f'{installation.mountpoint}/etc/X11/xinit/xinitrc', 'r') as xinitrc: with open(f'{installation.mountpoint}/etc/X11/xinit/xinitrc', 'r') as xinitrc:
xinitrc_data = xinitrc.read() xinitrc_data = xinitrc.read()
for line in xinitrc_data.split('\n'): for line in xinitrc_data.split('\n'):
if 'twm &' in line: xinitrc_data = xinitrc_data.replace(line, f"# {line}") if "twm &" in line:
if 'xclock' in line: xinitrc_data = xinitrc_data.replace(line, f"# {line}") xinitrc_data = xinitrc_data.replace(line, f"# {line}")
if 'xterm' in line: xinitrc_data = xinitrc_data.replace(line, f"# {line}") if "xclock" in line:
xinitrc_data = xinitrc_data.replace(line, f"# {line}")
if "xterm" in line:
xinitrc_data = xinitrc_data.replace(line, f"# {line}")
xinitrc_data += '\n' xinitrc_data += '\n'
xinitrc_data += 'exec awesome\n' xinitrc_data += 'exec awesome\n'
@ -22,4 +27,4 @@ with open(f'{installation.mountpoint}/etc/xdg/awesome/rc.lua', 'r') as awesome_r
awesome = awesome.replace('xterm', 'xterm -ls -xrm \\"XTerm*selectToClipboard: true\\"') awesome = awesome.replace('xterm', 'xterm -ls -xrm \\"XTerm*selectToClipboard: true\\"')
with open(f'{installation.mountpoint}/etc/xdg/awesome/rc.lua', 'w') as awesome_rc_lua: with open(f'{installation.mountpoint}/etc/xdg/awesome/rc.lua', 'w') as awesome_rc_lua:
awesome_rc_lua.write(awesome) awesome_rc_lua.write(awesome)

View File

@ -1,7 +1,8 @@
# A desktop environemtn using "Awesome" window manager. # A desktop environment using "Awesome" window manager.
import archinstall import archinstall
def _prep_function(*args, **kwargs): def _prep_function(*args, **kwargs):
""" """
Magic function called by the importing installer Magic function called by the importing installer
@ -18,6 +19,7 @@ def _prep_function(*args, **kwargs):
else: else:
print('Deprecated (??): xorg profile has no _prep_function() anymore') print('Deprecated (??): xorg profile has no _prep_function() anymore')
# Ensures that this code only gets executed if executed # Ensures that this code only gets executed if executed
# through importlib.util.spec_from_file_location("awesome", "/somewhere/awesome.py") # through importlib.util.spec_from_file_location("awesome", "/somewhere/awesome.py")
# or through conventional import awesome # or through conventional import awesome
@ -32,17 +34,19 @@ if __name__ == 'awesome':
# Then setup and configure the desktop environment: awesome # Then setup and configure the desktop environment: awesome
arguments = { arguments = {
#'keyboard_layout' : 'sv-latin1', #'keyboard_layout' : 'sv-latin1',
"editor" : "nano", "editor": "nano",
"mediaplayer" : "lollypop gstreamer gst-plugins-good gnome-keyring", "mediaplayer": "lollypop gstreamer gst-plugins-good gnome-keyring",
"filebrowser" : "nemo gpicview-gtk3", "filebrowser": "nemo gpicview-gtk3",
"webbrowser" : "chromium", "webbrowser": "chromium",
"window_manager" : "awesome", "window_manager": "awesome",
"virtulization" : "qemu ovmf", "virtulization": "qemu ovmf",
"utils" : "openssh sshfs git htop pkgfile scrot dhclient wget smbclient cifs-utils libu2f-host", "utils": "openssh sshfs git htop pkgfile scrot dhclient wget smbclient cifs-utils libu2f-host",
"audio" : "pulseaudio pulseaudio-alsa pavucontrol" "audio": "pulseaudio pulseaudio-alsa pavucontrol"
} }
installation.add_additional_packages("{webbrowser} {utils} {mediaplayer} {window_manager} {virtulization} {filebrowser} {editor}".format(**arguments)) installation.add_additional_packages(
"{webbrowser} {utils} {mediaplayer} {window_manager} {virtulization} {filebrowser} {editor}".format(
**arguments))
#with open(f'{installation.mountpoint}/etc/X11/xinit/xinitrc', 'a') as X11: #with open(f'{installation.mountpoint}/etc/X11/xinit/xinitrc', 'a') as X11:
# X11.write('setxkbmap se\n') # X11.write('setxkbmap se\n')
@ -56,7 +60,10 @@ if __name__ == 'awesome':
awesome_lua = awesome_rc_lua.read() awesome_lua = awesome_rc_lua.read()
# Insert slock as a shortcut on Modkey+l (window+l) # Insert slock as a shortcut on Modkey+l (window+l)
awesome_lua = awesome_lua.replace('\nglobalkeys = gears.table.join(', 'globalkeys = gears.table.join(\n awful.key({ modkey, }, \"l\", function() awful.spawn(\"slock &\") end,\n') awesome_lua = awesome_lua.replace(
"\nglobalkeys = gears.table.join(",
"globalkeys = gears.table.join(\n awful.key({ modkey, }, \"l\", function() awful.spawn(\"slock &\") end,\n"
)
# Insert some useful applications: # Insert some useful applications:
#awesome = awesome.replace('{ "open terminal", terminal, ','{ "Chromium", "chromium" },\n "open terminal", terminal, ') #awesome = awesome.replace('{ "open terminal", terminal, ','{ "Chromium", "chromium" },\n "open terminal", terminal, ')
@ -75,5 +82,6 @@ if __name__ == 'awesome':
awesome_rc_lua.write(awesome_lua) awesome_rc_lua.write(awesome_lua)
# Remove some interfering nemo settings # Remove some interfering nemo settings
installation.arch_chroot('gsettings set org.nemo.desktop show-desktop-icons false') installation.arch_chroot("gsettings set org.nemo.desktop show-desktop-icons false")
installation.arch_chroot('xdg-mime default nemo.desktop inode/directory application/x-gnome-saved-search') installation.arch_chroot(
"xdg-mime default nemo.desktop inode/directory application/x-gnome-saved-search")

View File

@ -1,4 +1,4 @@
# A desktop environemtn using "Awesome" window manager. # A desktop environment using "Gnome"
import archinstall import archinstall
@ -32,4 +32,4 @@ if __name__ == 'gnome':
installation.enable_service('gdm') # Gnome Display Manager installation.enable_service('gdm') # Gnome Display Manager
# We could also start it via xinitrc since we do have Xorg, # We could also start it via xinitrc since we do have Xorg,
# but for gnome that's deprecated and wayland is preferred. # but for gnome that's deprecated and wayland is preferred.

View File

@ -1,4 +1,4 @@
# A desktop environemtn using "Awesome" window manager. # A desktop environement using "KDE".
import archinstall, os import archinstall, os

View File

@ -1,4 +1,4 @@
# A desktop environemtn using "Awesome" window manager. # A system with "xorg" installed
import archinstall, os import archinstall, os