import os import logging import platform import sys try: from builder.configs import logger_config except ImportError as e: try: basic_logger = logging.getLogger(__name__) logging.basicConfig(level=logging.ERROR) 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) try: logger = logger_config.setup_logger('bootstrap') except NameError: logging.basicConfig(level=logging.INFO) logger = logging.getLogger('bootstrap') def filter_repositories_by_architecture(repositories_data, target_architecture): """ 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.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.get('uri')} for architecture {target_architecture}") return filtered_repo_args 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. Args: env_name (str): The name of the environment ('rootfs', 'pep-host', 'pep-target'). 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. Returns an empty list if no packages are defined or path is missing. Raises: ValueError: If no repositories found for the target architecture. KeyError: If target directory path is not found in paths. """ logger.info(f"=> Constructing xbps-install arguments for {env_name.upper()} ({target_architecture})...") target_directory_path = None if env_name == "rootfs": target_directory_path = paths.get("ROOTFS") elif env_name == "pep-host": target_directory_path = paths.get("PEPHOSTDIR") elif env_name == "pep-target": target_directory_path = paths.get("PEPTARGETDIR") else: logger.error(f"Unknown bootstrap environment: {env_name}") raise ValueError(f"Unknown bootstrap environment: {env_name}") if not target_directory_path: logger.error(f"Path for environment '{env_name}' not found in paths dictionary.") raise KeyError(f"Path for environment '{env_name}' not found.") packages_to_install = all_bootstrap_packages.get(env_name, {}).get(target_architecture, []) if not packages_to_install: logger.warning(f"No packages defined for {env_name} on architecture {target_architecture}. Skipping command construction.") return [] filtered_repo_args = filter_repositories_by_architecture(repositories_data, target_architecture) if not filtered_repo_args: logger.error(f"No repositories found supporting target architecture: {target_architecture}. Cannot construct command for {env_name}.") raise ValueError(f"No repositories found for architecture {target_architecture}") host_cachedir = os.path.join(os.getcwd(), "xbps_package_cache", target_architecture) os.makedirs(host_cachedir, exist_ok=True) logger.debug(f"Using XBPS cache directory (on host): {host_cachedir}") xbps_command_args = [ "-S", "-y", ] + filtered_repo_args + [ "-r", target_directory_path, "-c", host_cachedir, ] + packages_to_install logger.info(f"Constructed arguments for {env_name}: {xbps_command_args}") return xbps_command_args