builder_peppermint_void/builder/core/bootstrap/cache.py
2025-04-25 12:38:42 +00:00

110 lines
4.3 KiB
Python

"""
SPDX-FileCopyrightText: 2023-2025 PeppermintOS Team
(peppermintosteam@proton.me)
SPDX-License-Identifier: GPL-3.0-or-later
This module provides functions for caching and downloading packages using xbps-install.
It loads repository information from a YAML configuration file.
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 subprocess
import shutil
import logging
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.core.bootstrap.yaml_repo_loader import load_repositories_from_yaml
from builder.configs import logger_config
from builder.core.xbps_commands import xbps_commands
from builder.core.bootstrap.paths import paths
except ImportError as e:
print(f"Error importing necessary modules: {e}. Ensure your environment is set up correctly. Details: {e}")
sys.exit(1)
logger = logger_config.setup_logger('cache')
CACHE_DIR = paths["ISO_CACHE_DIR"]
def get_or_download_package(package_name, architecture, yaml_file_path):
"""
Checks if a package is in the cache for the specified architecture.
If not, it downloads the package to the cache using xbps-install.
Repository information is loaded from a YAML file.
Args:
package_name (str): The name of the package to obtain.
architecture (str): The target architecture (e.g., 'x86_64').
yaml_file_path (str): The path to the YAML file containing repository information.
Returns:
bool: True if the package is in the cache (or was downloaded), False on error.
"""
arch_cache_dir = os.path.join(CACHE_DIR, architecture)
os.makedirs(arch_cache_dir, exist_ok=True)
host_arch = os.uname().machine
xbps_cachedir_env = os.path.join(os.getcwd(), CACHE_DIR, architecture)
xbps_host_cachedir_env = os.path.join(os.getcwd(), CACHE_DIR, host_arch)
env = os.environ.copy()
env["XBPS_CACHEDIR"] = xbps_cachedir_env
env["XBPS_HOST_CACHEDIR"] = xbps_host_cachedir_env
env["XBPS_ARCH"] = architecture
xbps_repository_arg = ""
repositories_data = load_repositories_from_yaml(yaml_file_path)
for repo in repositories_data.get('repositories', []):
if architecture in repo.get('architectures', []):
xbps_repository_arg += f"--repository={repo.get('uri')} "
download_cmd = [xbps_commands["XBPS_INSTALL_CMD"], "-yn", "-c", xbps_cachedir_env]
download_cmd.extend(xbps_repository_arg.split())
download_cmd.append(package_name)
def sync_repositories(architecture, yaml_file_path):
repositories_data = load_repositories_from_yaml(yaml_file_path)
repo_urls = []
for repo in repositories_data.get('repositories', []):
if architecture in repo.get('architectures', []):
repo_urls.append(repo.get('uri'))
if not repo_urls:
logger.warning(f"No repositories found for architecture '{architecture}' in the YAML file to synchronize.")
return
xbps_repo_arg = ""
for url in repo_urls:
xbps_repo_arg += f"--repository={url} "
rootfs_path = paths["ROOTFS"]
sync_cmd = [xbps_commands["XBPS_INSTALL_CMD"], "-S", "-y", "-r", rootfs_path]
sync_cmd.extend(xbps_repo_arg.split())
env = os.environ.copy()
env["XBPS_ARCH"] = architecture
try:
logger.info(f"Synchronizing repository information for architecture '{architecture}' in rootfs '{rootfs_path}'...")
logger.debug(f"Executing command: {' '.join(sync_cmd)}")
result = subprocess.run(sync_cmd, env=env, check=True, text=True, capture_output=True)
logger.debug(result.stdout)
logger.info(f"Repository synchronization for '{architecture}' completed.")
except subprocess.CalledProcessError as e:
logger.error(f"Error synchronizing repositories for '{architecture}': {e}")
if e.stderr:
logger.error(f"Stderr from xbps-install: {e.stderr}")
except FileNotFoundError:
logger.error(f"Error: xbps-install command not found in: {xbps_commands['XBPS_INSTALL_CMD']}")