#!/usr/bin/env python3 # Copyright (C) 2023 Rudra Saraswat # Licensed under GPL-3.0. # Error codes # 1 - Partitioning error # 3 - Username not allowed import os import sys import json import yaml import signal import subprocess if os.environ.get('TESTING_INST') == 'true': testing = True else: testing = False # State variables mountpoints = [] ######################################################################################## # Helper utils def preexec(): signal.signal(signal.SIGHUP, signal.SIG_IGN) signal.signal(signal.SIGINT, signal.SIG_IGN) signal.signal(signal.SIGQUIT, signal.SIG_IGN) def exec(cmd): if testing: print(' '.join(cmd)) else: subprocess.call(cmd, shell=False, stdout=sys.stdout, stderr=sys.stderr, preexec_fn=preexec) def enable_service(service): exec(['systemctl', 'enable', service]) def enable_user_service(service): exec(['systemctl', '--global', 'enable', service]) def mount(part, path): exec(['mount', part, path]) def mkdir(path): exec(['mkdir', '-p', path]) ######################################################################################## # Setup base def inst_system_config(config): system_config = { 'arch-repo': 'https://geo.mirror.pkgbuild.com', 'repo': 'https://pkg-repo.blendos.co', 'impl': 'http://github.com/blend-os/tracks/raw/main', 'track': 'default-gnome' } if 'NVIDIA' in subprocess.check_output(['lspci']).decode('utf-8'): system_config['packages'] = [ 'nvidia-dkms', 'nvidia-prime', 'switcheroo-control' ] system_config['services'] = [ 'switcheroo-control' ] if testing == False: with open('/system.yaml', 'w') as system_config_file: yaml.dump(system_config, system_config_file) else: print(system_config) ######################################################################################## # Locale def inst_locale(config): # Set locale exec(['bash', '-c', 'echo \'en_US.UTF-8 UTF-8\' > /etc/locale.gen']) first_locale = True for locale in config['locale']['locale']: if locale != 'en_US.UTF-8 UTF-8': exec( ['bash', '-c', f'echo \'{locale}\' >> /etc/locale.gen']) if first_locale: exec( ['bash', '-c', f'echo \'LANG={locale.split()[0]}\' > /etc/locale.conf']) first_locale = False exec(['locale-gen']) # Set keyboard layout exec( ['bash', '-c', f'echo \'KEYMAP={config["locale"]["keymap"]}\' > /etc/vconsole.conf']) # Set timezone exec( ['ln', '-sf', f'/usr/share/zoneinfo/{config["locale"]["timezone"]}', '/etc/localtime']) ######################################################################################## # Networking def inst_networking(config): # Set hostname exec( ['bash', '-c', f'echo \'{config["networking"]["hostname"]}\' > /etc/hostname']) # Create hosts file exec(['bash', '-c', 'echo \'127.0.0.1 localhost\' > /etc/hosts']) if config['networking']['ipv6']: # Enable ipv6 exec(['bash', '-c', 'echo \'::1 localhost\' > /etc/hosts']) ######################################################################################## # Users def inst_users(config): for home_dir in os.listdir('/home'): if not home_dir == 'blend': exec(['rm', '-rf', '/home/' + home_dir]) # Add users for user in config['users']: exec(['useradd', '-m', '-s', '/bin/bash', user['name']]) exec(['usermod', '-c', user['fullname'], user['name']]) exec( ['bash', '-c', f'echo \'{user["name"]}:{user["password"]}\' | chpasswd']) exec(['usermod', '-aG', 'wheel', user['name']]) # Add AccountsService user file mkdir('/mnt/var/lib/AccountsService/users') exec( ['bash', '-c', f'echo "[User]" > /var/lib/AccountsService/users/{user["name"]}']) exec( ['bash', '-c', f'echo "SystemAccount=false" >> /var/lib/AccountsService/users/{user["name"]}']) # Create ~/.local/share/applications with right perms exec(['sudo', '-u', user['name'], 'mkdir', '-p', f'/home/{user["name"]}/.local/share/applications']) ######################################################################################## # Akshara def inst_akshara(): exec(['env', 'AKSHARA_INSTALL=1', 'akshara', 'update']) ######################################################################################## signal.signal(signal.SIGHUP, signal.SIG_IGN) signal.signal(signal.SIGINT, signal.SIG_IGN) signal.signal(signal.SIGQUIT, signal.SIG_IGN) try: if sys.argv[1] == 'config' and os.path.isfile(sys.argv[2]): with open(sys.argv[2]) as config_file: config = json.load(config_file) inst_system_config(config) inst_locale(config) inst_networking(config) inst_users(config) inst_akshara() print() print('===========') print('Successful.') sys.exit() except IndexError: pass