diff --git a/builder/core/bootstrap/bootstrap.py b/builder/core/bootstrap/bootstrap.py index 3b2047c6..2561d7d5 100644 --- a/builder/core/bootstrap/bootstrap.py +++ b/builder/core/bootstrap/bootstrap.py @@ -1,38 +1,70 @@ -# builder/core/bootstrap.py (Revised) +# builder/core/bootstrap.py (Apenas Construção de Argumentos) import os import logging import platform import sys +# shutil não é necessário neste ficheiro com esta estratégia -base_dir = os.path.dirname(os.path.dirname(os.path.dirname(os.path.abspath(__file__)))) -sys.path.insert(0, base_dir) +# base_dir e sys.path.insert são geralmente feitos no script principal +# from builder.core.bootstrap.paths import paths # Não é necessário importar paths aqui try: from builder.configs import logger_config - from builder.core.command_runner import run_command + # from builder.core.command_runner import run_command # Não precisamos de run_command neste ficheiro com esta estratégia except ImportError as e: - logging.error(f"Error importing necessary modules: {e}. Ensure your environment is set up correctly.") + # Usar print ou logger básico se logger_config falhar + try: + basic_logger = logging.getLogger(__name__) + logging.basicConfig(level=logging.ERROR) # Configurar um logger básico para erro + basic_logger.error(f"Error importing necessary modules for bootstrap helper: {e}. Ensure your environment is set up correctly.") + except Exception: + print(f"Error importing necessary modules for bootstrap helper: {e}. Ensure your environment is set up correctly.") sys.exit(1) -logger = logger_config.setup_logger('bootstrap') + +# Configurar logger para este módulo +try: + logger = logger_config.setup_logger('bootstrap') +except NameError: + # Fallback logger se logger_config não estiver disponível + logging.basicConfig(level=logging.INFO) # Nível INFO por padrão para este helper + logger = logging.getLogger('bootstrap') + def filter_repositories_by_architecture(repositories_data, target_architecture): - # ... (Keep this function as is) ... + """ + Filters the list of repositories to include only those supporting the target architecture. + + Args: + repositories_data (list): A list of repository dictionaries, + each potentially having an 'architectures' key. + target_architecture (str): The target architecture (e.g., 'aarch64', 'i686', 'x86_64'). + + Returns: + list: A list of '-R ' strings for the relevant repositories. + """ filtered_repo_args = [] + if not isinstance(repositories_data, list): + logger.error("repositories_data must be a list.") + return [] + for repo in repositories_data: + if not isinstance(repo, dict): + logger.warning(f"Repository entry is not a dictionary: {repo}. Skipping.") + continue + if 'uri' in repo and ('architectures' not in repo or target_architecture in repo['architectures']): filtered_repo_args.extend(["-R", repo['uri']]) - logger.debug(f"Including repository {repo['uri']} for architecture {target_architecture}") + logger.debug(f"Including repository {repo.get('uri')} for architecture {target_architecture}") else: if 'uri' not in repo: logger.warning(f"Repository entry missing 'uri' key: {repo}. Skipping.") else: - logger.debug(f"Excluding repository {repo['uri']} for architecture {target_architecture}") + logger.debug(f"Excluding repository {repo.get('uri')} for architecture {target_architecture}") return filtered_repo_args -# MODIFIED: This function now only returns the arguments for xbps-install, does NOT execute def construct_xbps_install_args(env_name, paths, target_architecture, repositories_data, all_bootstrap_packages): """ Constructs the xbps-install command arguments for a specific environment. @@ -42,8 +74,10 @@ def construct_xbps_install_args(env_name, paths, target_architecture, repositori paths (dict): Dictionary of build paths. target_architecture (str): The target architecture for the bootstrap. repositories_data (list): List of repository dictionaries from YAML config. + Expected structure: [{'name': '...', 'uri': '...', 'architectures': [...]}, ...] all_bootstrap_packages (dict): Dictionary containing package lists for different environments and architectures. + Expected structure: {'env_name': {'arch': ['pkg1', ...]}} Returns: list: A list of strings representing the xbps-install command arguments. @@ -53,7 +87,7 @@ def construct_xbps_install_args(env_name, paths, target_architecture, repositori ValueError: If no repositories found for the target architecture. KeyError: If target directory path is not found in paths. """ - logger.debug(f"Constructing xbps-install arguments for {env_name.upper()} ({target_architecture})...") + logger.info(f"=> Constructing xbps-install arguments for {env_name.upper()} ({target_architecture})...") target_directory_path = None if env_name == "rootfs": @@ -89,6 +123,7 @@ def construct_xbps_install_args(env_name, paths, target_architecture, repositori logger.debug(f"Using XBPS cache directory (on host): {host_cachedir}") # Construct the xbps-install command arguments + # This command will be run directly on the host, targeting the specified directory (-r) xbps_command_args = [ "-S", "-y", ] + filtered_repo_args + [ @@ -96,31 +131,5 @@ def construct_xbps_install_args(env_name, paths, target_architecture, repositori "-c", host_cachedir, # XBPS cache directory (path on host) ] + packages_to_install - logger.debug(f"Constructed arguments for {env_name}: {xbps_command_args}") + logger.info(f"Constructed arguments for {env_name}: {xbps_command_args}") return xbps_command_args - - -# NEW FUNCTION: Helper to run a command inside a chroot -def run_command_in_chroot(chroot_path, command_list): - """ - Executes a command inside a specified chroot environment. - - Args: - chroot_path (str): The path on the host to the root of the chroot environment. - command_list (list): The list of strings representing the command and its arguments - *as they would be run directly*, e.g., ['/usr/bin/xbps-install', ...]. - The function adds the 'sudo chroot chroot_path' wrapper. - - Raises: - subprocess.CalledProcessError: If the command fails inside the chroot. - """ - # Construct the chroot command wrapper - chroot_wrapper = ["sudo", "chroot", chroot_path] - - # Combine the wrapper with the command to be run inside the chroot - full_command = chroot_wrapper + command_list - - logger.info(f"Executing command in chroot {chroot_path}: {' '.join(full_command)}") - run_command(full_command) # Use the existing run_command helper - -# Removed generate_bootstrap_commands and __main__ block \ No newline at end of file diff --git a/builder/iso_builder.py b/builder/iso_builder.py index e6048957..6054f626 100644 --- a/builder/iso_builder.py +++ b/builder/iso_builder.py @@ -43,7 +43,6 @@ try: from builder.configs import logger_config from builder.core.customize_system import customize_system from builder.core.copy_customizations import copy_custom_files - from builder.core.bootstrap.cache import get_or_download_package, sync_repositories from builder.core.final_cleanup import remove_fusato_directory from builder.core.move_iso import move_and_cleanup_iso from builder.core.bootstrap import bootstrap @@ -124,40 +123,61 @@ def iso_builder_main( all_bootstrap_packages = repo_data.get('bootstrap_packages', {}) if build_rootfs: - bootstrap.run_bootstrap_for_environment( + logger.info("=> Initiating the Void Linux system bootstrap for ROOTFS (host execution)...") + + rootfs_bootstrap_args = bootstrap.construct_xbps_install_args( "rootfs", paths, architecture, - host_arch, repositories, all_bootstrap_packages ) - logger.info("=> Void Linux ROOTFS bootstrap COMPLETE.") + + if rootfs_bootstrap_args: + initial_bootstrap_command = ["/usr/bin/xbps-install"] + rootfs_bootstrap_args + logger.info(f"Executing initial ROOTFS bootstrap command (host): {' '.join(initial_bootstrap_command)}") + run_command(initial_bootstrap_command) + logger.info("=> Void Linux ROOTFS initial bootstrap COMPLETE.") + else: + logger.warning("Skipping ROOTFS bootstrap due to no packages defined or error.") + + mount_essential_filesystems_in_chroot(paths, logger) + logger.info("=> Essential filesystems mounted in the ROOTFS.") if build_pephost: - bootstrap.run_bootstrap_for_environment( - "pep-host", - paths, - architecture, - host_arch, - repositories, - all_bootstrap_packages + logger.info("=> Initiating the Void Linux system bootstrap for PEP-HOST (host execution)...") + + pephost_bootstrap_args = bootstrap.construct_xbps_install_args( + "pep-host", paths, architecture, repositories, all_bootstrap_packages ) - logger.info("=> Void Linux PEP-HOST bootstrap COMPLETE.") + + if pephost_bootstrap_args: + pephost_bootstrap_command = ["/usr/bin/xbps-install"] + pephost_bootstrap_args + logger.info(f"Executing PEP-HOST bootstrap command (host): {' '.join(pephost_bootstrap_command)}") + run_command(pephost_bootstrap_command) + logger.info("=> Void Linux PEP-HOST bootstrap COMPLETE.") + else: + logger.warning("Skipping PEP-HOST bootstrap due to no packages defined or error.") if build_peptarget: - bootstrap.run_bootstrap_for_environment( - "pep-target", - paths, - architecture, - host_arch, - repositories, - all_bootstrap_packages + logger.info("=> Initiating the Void Linux system bootstrap for PEP-TARGET (host execution)...") + + peptarget_bootstrap_args = bootstrap.construct_xbps_install_args( + "pep-target", paths, architecture, repositories, all_bootstrap_packages ) - logger.info("=> Void Linux PEP-TARGET bootstrap COMPLETE.") + + if peptarget_bootstrap_args: + peptarget_bootstrap_command = ["/usr/bin/xbps-install"] + peptarget_bootstrap_args + logger.info(f"Executing PEP-TARGET bootstrap command (host): {' '.join(peptarget_bootstrap_command)}") + run_command(peptarget_bootstrap_command) + logger.info("=> Void Linux PEP-TARGET bootstrap COMPLETE.") + else: + logger.warning("Skipping PEP-TARGET bootstrap due to no packages defined or error.") + 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.")