diff --git a/builder/core/packages_install.py b/builder/core/packages_install.py index 31d9fbbd..3ea6e217 100644 --- a/builder/core/packages_install.py +++ b/builder/core/packages_install.py @@ -1,3 +1,5 @@ +# Assuming this is in builder/core/packages_install.py + # -*- coding: utf-8 -*- """ SPDX-FileCopyrightText: 2023-2025 PeppermintOS Team @@ -7,11 +9,8 @@ SPDX-License-Identifier: GPL-3.0-or-later This module is responsible for installing common packages into the root filesystem (rootfs) of the PeppermintOS build. It reads the list of packages to be installed from a YAML file -and uses the XBPS package manager to perform the installation. - -The module handles loading package lists based on categories defined in the YAML file -and configures the XBPS command with the appropriate rootfs path, cache directory, -and repository URLs for the target architecture. +and uses the XBPS package manager to perform the installation according to the +host-execution strategy. Credits: - PeppermintOS Team (peppermintosteam@proton.me) - Development and maintenance of the project. @@ -27,102 +26,120 @@ import logging import sys import os -BASE_DIR = os.path.dirname(os.path.dirname(os.path.abspath(__file__))) -sys.path.insert(0, BASE_DIR) +# BASE_DIR and sys.path.insert might be needed at the top of this file too if it's run standalone +# BASE_DIR = os.path.dirname(os.path.dirname(os.path.abspath(__file__))) +# sys.path.insert(0, BASE_DIR) try: + # Import modules used by this function from builder.core.command_runner import run_command - from builder.core.xbps_commands import xbps_commands - from builder.configs import logger_config # Import the logger_config module - from builder.core.bootstrap.paths import paths + # xbps_commands is likely not needed here as construct_xbps_install_args handles it + # from builder.core.xbps_commands import xbps_commands + from builder.configs import logger_config + # paths is passed as argument, so not needed as direct import + # from builder.core.bootstrap.paths import paths + from builder.core.config_loader import load_yaml_config # Needed to load common packages YAML + from builder.core import bootstrap # Import bootstrap module for construct_xbps_install_args - logger = logger_config.setup_logger('packages_install') # Pass the 'packages_install' argument + logger = logger_config.setup_logger('packages_install') # Setup logger for this module except ImportError as e: - print(f"Error importing necessary modules: {e}. Ensure your environment is set up correctly.") + # Handle import error for this module + try: + basic_logger = logging.getLogger(__name__) + logging.basicConfig(level=logging.ERROR) + basic_logger.error(f"Error importing necessary modules for packages_install: {e}. Ensure your environment is set up correctly.") + except Exception: + print(f"Error importing necessary modules for packages_install: {e}. Ensure your environment is set up correctly.") sys.exit(1) -def install_common_packages_rootfs_yaml(rootfs_path, package_yaml_file, arch): +# MODIFIED FUNCTION SIGNATURE to accept 5 arguments, using names from the call in iso_builder_main +# Note: The first argument name 'rootfs_path' is kept for clarity but the actual rootfs path +# will be obtained from the 'paths' dictionary passed as the first argument. +def install_common_packages_rootfs_yaml(paths, common_packages_yaml_path, target_architecture, host_architecture, repositories_data): """ - Installs common packages into the rootfs by reading the package lists from a YAML file. + Installs common packages into the rootfs from a YAML file, using the host-execution strategy. Args: - rootfs_path (str): Path to the rootfs directory. - package_yaml_file (str): Path to the YAML file containing the common package lists. - arch (str): Architecture (e.g., 'x86_64'). + paths (dict): Dictionary of build paths. Required to get rootfs path and cache dir. + common_packages_yaml_path (str): Path to the YAML file containing the common package lists. + Expected structure: {: [package list]} + target_architecture (str): The target architecture (e.g., 'aarch64'). + host_architecture (str): The architecture of the host system. + repositories_data (list): List of repository dictionaries from YAML config. + Expected structure: [{'name': '...', 'uri': '...', 'architectures': [...]}, ...] + + Raises: + subprocess.CalledProcessError: If the xbps-install command fails. + ValueError: If configuration data is missing or incorrect. + KeyError: If required paths are not found. """ - logger = logging.getLogger(__name__) # Initialize logger here - logger.info(f"=> Installing common packages into ROOTFS using YAML: {package_yaml_file}") + # Re-initialize logger if needed, or rely on module-level logger + # logger = logging.getLogger(__name__) # Remove this line if logger is setup at module level + logger.info(f"=> Installing common packages into ROOTFS ({target_architecture}) using YAML: {common_packages_yaml_path}") + # Ensure paths dict is available + if not isinstance(paths, dict): + logger.error("Paths dictionary is missing or incorrect.") + raise ValueError("Paths dictionary is required.") + + # Get the actual rootfs path from the paths dictionary + rootfs_path = paths.get("ROOTFS") + if not rootfs_path: + logger.error(f"Path for environment 'rootfs' not found in paths dictionary.") + raise KeyError(f"Path for environment 'rootfs' not found.") + + + # Load common packages configuration from the specified YAML path + # Assumes common_packages_yaml_path points to a YAML structured like {arch: [package list]} try: - with open(package_yaml_file, 'r') as f: - common_packages_config = yaml.safe_load(f) # Load the YAML - except FileNotFoundError: - logger.error(f"Package YAML file not found: {package_yaml_file}") - return - except yaml.YAMLError as e: - logger.error(f"Error reading the YAML file: {package_yaml_file} - {e}") - return + common_packages_config = load_yaml_config(common_packages_yaml_path, os.path.basename(common_packages_yaml_path)) + except Exception as e: # load_yaml_config should handle FileNotFoundError/YAMLError + logger.error(f"Error loading common packages YAML '{common_packages_yaml_path}': {e}") + raise # Re-raise the exception - total_package_list = [] + # Get the list of common packages specifically for the target architecture + # The YAML structure is expected to be {: [package1, package2, ...]} + common_packages_for_arch = common_packages_config.get(target_architecture, []) - package_categories = [ - 'accessibility_packages', - 'core_packages', - 'xorg_packages', - 'firmware_packages', - 'shared_packages', - 'installer_packages' - ] + if not common_packages_for_arch: + logger.warning(f"No common packages defined for architecture {target_architecture} in {common_packages_yaml_path}. Skipping installation.") + return # Exit the function - for category in package_categories: - if category in common_packages_config: # Check if the category exists in the YAML - category_packages = common_packages_config[category] - if isinstance(category_packages, list): # Check if it's a list - total_package_list.extend(category_packages) # Add to the total list - else: - logger.warning(f"Category '{category}' in {package_yaml_file} is not a list of packages. Ignoring.") - else: - logger.warning(f"Category '{category}' not found in {package_yaml_file}. Ignoring.") + # Construct the xbps-install command arguments using the helper from bootstrap module + # construct_xbps_install_args expects the package list in the structure {'env_name': {'arch': [package_list]}} + # So, we adapt the common package list for the target architecture into this structure temporarily. + # We pass "rootfs" as env_name because we are installing into the rootfs environment. + adapted_package_structure = {"rootfs": {target_architecture: common_packages_for_arch}} - if not total_package_list: - logger.warning("No common package lists found in the YAML. Proceeding without installing common packages.") - return + # construct_xbps_install_args handles repository filtering, -r, -c args internally + # It needs paths, target_architecture, repositories_data, and the adapted package structure + common_packages_args = bootstrap.construct_xbps_install_args( + "rootfs", # Environment name for paths/package lookup within the structure + paths, # Paths dictionary (needed by construct_xbps_install_args for rootfs path and cache) + target_architecture, # Target architecture + repositories_data, # All repository data + adapted_package_structure # Pass common packages in the structure expected by construct_xbps_install_args + ) - # *** LOAD REPOSITORY CONFIGURATION FROM YAML *** - repos_yaml_file = paths['REPOS_YAML_FILE'] + if not common_packages_args: + logger.warning("Skipping common packages installation due to failure in constructing xbps-install arguments.") + # The error was likely logged within construct_xbps_install_args + return # Exit the function + + + # Execute the xbps-install command directly on the host, targeting the rootfs + # Prepend the xbps-install binary path on the host + common_install_command = ["/usr/bin/xbps-install"] + common_packages_args + + logger.info(f"Executing common packages installation command (host): {' '.join(common_install_command)}") try: - with open(repos_yaml_file, 'r') as f: - repo_data = yaml.safe_load(f) - except FileNotFoundError: - logger.error(f"Repository YAML file not found: {repos_yaml_file}") - return - except yaml.YAMLError as e: - logger.error(f"Error reading the repository YAML file: {repos_yaml_file} - {e}") - return - - repositories = repo_data.get('repositories', []) - - xbps_install_command = [ - xbps_commands["XBPS_INSTALL_CMD"], '-S', '-y', - '-r', rootfs_path, - '-c', os.path.join(paths["ISO_CACHE_DIR"], arch) # Add the -c flag and the path to the cache directory - ] - - for repo_dict in repositories: - if arch in repo_dict.get('architectures', []): # Add repositories only for the target architecture - repo_url = repo_dict['uri'] - xbps_install_command.extend(['-R', repo_url]) - - xbps_install_command.extend(total_package_list) - - command_str = " ".join(xbps_install_command) # For more readable logging - logger.info(f"=> Generated XBPS_INSTALL_CMD for common packages: {command_str}") - - try: - logger.info(f"=> Executing XBPS_INSTALL_CMD for common packages [TARGETED AT: {rootfs_path}]") - run_command(xbps_install_command) + run_command(common_install_command) # Use the existing run_command helper logger.info(f"=> Installation of common packages into ROOTFS completed.") - except Exception as e: + except Exception as e: # Catching general Exception, consider more specific CalledProcessError logger.error(f"Error executing XBPS_INSTALL_CMD for common packages: {e}") - raise \ No newline at end of file + raise # Re-raise the exception to stop the build + +# Note: The hardcoded package_categories list and the loop over it are removed +# as the packages are now expected to be listed directly under the architecture key in the YAML. +# The loading of repos_yaml_file inside this function is removed as repositories_data is passed. \ No newline at end of file diff --git a/builder/iso_builder.py b/builder/iso_builder.py index 6054f626..53e1955d 100644 --- a/builder/iso_builder.py +++ b/builder/iso_builder.py @@ -177,10 +177,6 @@ def iso_builder_main( logger.info("=> Void Linux system bootstrap (ROOTFS, PEP-HOST, PEP-TARGET) COMPLETE.") - - mount_essential_filesystems_in_chroot(paths, logger) - logger.info("=> Essential filesystems mounted in the chroot.") - logger.info("=> Copying network configuration files to ROOTFS...") copy_system_files.copy_network_config_files_to_chroot(paths['ROOTFS']) logger.info("=> Network configuration files copied to ROOTFS.") @@ -189,10 +185,13 @@ def iso_builder_main( ficheiro_pacotes_desktop_yaml = f'builder/configs/desktops/{desktop_selecionado}.yaml' iso_build_config['desktop'] = desktop iso_build_config['kernel_type'] = kernel_type - - common_packages = load_yaml_config('builder/configs/packages/common_packages.yaml', 'common_packages.yaml') - install_common_packages_rootfs_yaml(paths["ROOTFS"], paths["COMMON_PACKAGES_YAML"], architecture, host_arch, repositories) - + install_common_packages_rootfs_yaml( + paths, + paths["COMMON_PACKAGES_YAML"], + architecture, + host_arch, + repositories + ) desktop_config = load_yaml_config(ficheiro_pacotes_desktop_yaml, desktop_selecionado + ".yaml") install_desktop_environment( arch=architecture,