# -*- coding: utf-8 -*- """ SPDX-FileCopyrightText: 2023-2025 PeppermintOS Team (peppermintosteam@proton.me) SPDX-License-Identifier: GPL-3.0-or-later This module provides a function to customize the bootstrapped Void Linux system within the root filesystem. It handles tasks such as setting the hostname, locale, timezone, configuring PipeWire based on the desktop environment, and setting up Plymouth if enabled. Credits: - PeppermintOS Team (peppermintosteam@proton.me) - Development and maintenance of the project. License: This code is distributed under the GNU General Public License version 3 or later (GPL-3.0-or-later). For more details, please refer to the LICENSE file included in the project or visit: https://www.gnu.org/licenses/gpl-3.0.html """ import os import logging import sys import subprocess BASE_DIR = os.path.dirname(os.path.dirname(os.path.abspath(__file__))) sys.path.insert(0, BASE_DIR) try: from builder.core.bootstrap.paths import paths from builder.core.xbps_commands import xbps_commands from builder.configs import logger_config from builder.core.command_runner import run_command from builder.core.customize_system_functions import setup_pipewire_in_rootfs from builder.core.config_loader import load_yaml_config except ImportError as e: print(f"Error importing necessary modules: {e}. Ensure your environment is set up correctly.") sys.exit(1) logger = logger_config.setup_logger('customize_system') def customize_system(arch, desktop, kernel_type, iso_build_config): """ Customizes the bootstrapped Void Linux system (e.g., hostname, fstab, locale, timezone) using external configurations. Args: arch (str): The architecture of the system being customized. desktop (str): The desktop environment being configured. kernel_type (str): The type of kernel installed. iso_build_config (dict): The configuration for the ISO build process. """ logging.info("=> Starting system customization using configurations...") hostname = iso_build_config.get('iso', {}).get('hostname', 'pep-live') logging.info("=> Setting hostname...") hostname_path = os.path.join(paths['ROOTFS'], 'etc', 'hostname') with open(hostname_path, 'w') as f: f.write(hostname + '\n') logging.info(f"=> Hostname set to: {hostname}") locale = iso_build_config.get('iso', {}).get('default_locale', 'en_US.UTF-8') logging.info("=> Configuring locale...") locale_gen_path = os.path.join(paths['ROOTFS'], 'etc', 'locale.gen') with open(locale_gen_path, 'w') as locale_gen_file: locale_gen_file.write(f"{locale} UTF-8\n") locale_conf_path = os.path.join(paths['ROOTFS'], 'etc', 'locale.conf') with open(locale_conf_path, 'w') as locale_conf_file: locale_conf_file.write(f"LANG={locale}\n") logging.info(f"=> Locale configured to {locale}") reconfigure_locales_cmd = [xbps_commands["XBPS_RECONFIGURE_CMD"], '-f', 'glibc-locales', '-r', paths['ROOTFS']] logger.info(f"=> Reconfiguring glibc-locales...") run_command(reconfigure_locales_cmd) logger.info("=> glibc-locales reconfigured.") timezone = iso_build_config.get('iso', {}).get('default_timezone', 'America/New_York') logging.info(f"=> Configuring Timezone to: {timezone}...") timezone_path = os.path.join(paths['ROOTFS'], 'etc', 'timezone') os.symlink(os.path.join('/usr/share/zoneinfo', timezone), timezone_path) logging.info(f"=> Timezone configured to: {timezone}") desktop_config_path = f'builder/configs/desktops/{desktop}.yaml' desktop_config = load_yaml_config(desktop_config_path, os.path.basename(desktop_config_path)) pipewire_config = desktop_config.get('pipewire', {}) setup_pipewire_in_rootfs(paths['ROOTFS'], arch, pipewire_config) plymouth_config = iso_build_config.get('iso_config', {}).get('iso', {}).get('plymouth') if plymouth_config and plymouth_config.get('enable'): plymouth_theme = plymouth_config.get('theme') logger.info(f"=> Configuring Plymouth with theme: {plymouth_theme}") rootfs_path = paths['ROOTFS'] plymouth_defaults_path_chroot = os.path.join(rootfs_path, 'usr', 'share', 'plymouth', 'plymouthd.defaults') try: with open(plymouth_defaults_path_chroot, 'r') as f: lines = f.readlines() modified_lines = [] theme_found = False for line in lines: if line.startswith('Theme='): modified_lines.append(f'Theme={plymouth_theme}\n') theme_found = True else: modified_lines.append(line) if not theme_found: modified_lines.append(f'Theme={plymouth_theme}\n') with open(plymouth_defaults_path_chroot, 'w') as f: f.writelines(modified_lines) logger.info(f"=> Tema do Plymouth definido diretamente em {plymouth_defaults_path_chroot}: {plymouth_theme}") except FileNotFoundError: logger.error(f"=> Ficheiro não encontrado: {plymouth_defaults_path_chroot}") except Exception as e: logger.error(f"=> Ocorreu um erro ao modificar {plymouth_defaults_path_chroot}: {e}") if plymouth_config and plymouth_config.get('enable'): plymouth_theme = plymouth_config.get('theme') logger.info(f"=> Configuring Plymouth with theme: {plymouth_theme}") rootfs_path = paths['ROOTFS'] set_theme_command = ['chroot', rootfs_path, '/usr/sbin/plymouth-set-default-theme', plymouth_theme] logger.info(f"=> Setting default Plymouth theme (chroot): {plymouth_theme}") try: subprocess.run(set_theme_command, check=True) except subprocess.CalledProcessError as e: logger.error(f"=> Erro ao executar o comando: {e}") except FileNotFoundError as e: logger.error(f"=> Ficheiro ou diretório não encontrado: {e}") update_initramfs_command = ['chroot', rootfs_path, '/usr/sbin/xbps-reconfigure', '-f', 'linux-base'] logger.info("=> Updating the initramfs to include Plymouth (chroot).") try: subprocess.run(update_initramfs_command, check=True) except subprocess.CalledProcessError as e: logger.error(f"=> Erro ao executar o comando: {e}") except FileNotFoundError as e: logger.error(f"=> Ficheiro ou diretório não encontrado: {e}") else: logger.info("=> Plymouth not enabled in configuration, skipping configuration.") grub_config = iso_build_config.get('iso_config', {}).get('grub', {}) grub_file_path_chroot = os.path.join(rootfs_path, 'etc', 'default', 'grub') if grub_config: try: with open(grub_file_path_chroot, 'r') as f: lines = f.readlines() modified_lines = [] for line in lines: found = False for key, value in grub_config.items(): if line.startswith(f'{key}='): modified_lines.append(f'{key}="{value}"\n') found = True break if not found: modified_lines.append(line) # Adicionar novas variáveis que não existiam existing_keys = [line.split('=')[0] for line in modified_lines if '=' in line] for key, value in grub_config.items(): if key not in existing_keys: modified_lines.append(f'{key}="{value}"\n') with open(grub_file_path_chroot, 'w') as f: f.writelines(modified_lines) logger.info(f"=> Ficheiro /etc/default/grub configurado com base em iso_config.") except FileNotFoundError: logger.error(f"=> Ficheiro não encontrado: {grub_file_path_chroot}") except Exception as e: logger.error(f"=> Ocorreu um erro ao modificar {grub_file_path_chroot}: {e}") else: logger.info(f"=> Nenhuma configuração GRUB encontrada em iso_config, skipping.") logging.info("=> System customization completed using configurations.")