# builder/core/bootstrap.py (Revised) import os import logging import platform import sys base_dir = os.path.dirname(os.path.dirname(os.path.dirname(os.path.abspath(__file__)))) sys.path.insert(0, base_dir) try: from builder.configs import logger_config from builder.core.command_runner import run_command except ImportError as e: logging.error(f"Error importing necessary modules: {e}. Ensure your environment is set up correctly.") sys.exit(1) logger = logger_config.setup_logger('bootstrap') def filter_repositories_by_architecture(repositories_data, target_architecture): # ... (Keep this function as is) ... filtered_repo_args = [] for repo in repositories_data: 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}") 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}") 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. 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. all_bootstrap_packages (dict): Dictionary containing package lists for different environments and architectures. 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.debug(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 [] # Return empty list if no packages 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}") # Get the XBPS cache directory for the target architecture (on the host) 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}") # Construct the xbps-install command arguments xbps_command_args = [ "-S", "-y", ] + filtered_repo_args + [ "-r", target_directory_path, # Install to the target directory (path on host) "-c", host_cachedir, # XBPS cache directory (path on host) ] + packages_to_install logger.debug(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