204 lines
10 KiB
Python
204 lines
10 KiB
Python
# Assuming this is in builder/core/install_desktop.py
|
||
|
||
# -*- coding: utf-8 -*-
|
||
"""
|
||
SPDX-FileCopyrightText: 2023-2025 PeppermintOS Team
|
||
(peppermintosteam@proton.me)
|
||
|
||
SPDX-License-Identifier: GPL-3.0-or-later
|
||
|
||
This module provides a function to install a specified desktop environment and enable
|
||
associated services, using the host-execution strategy and handling architecture-specific
|
||
package lists and services defined in YAML configuration files.
|
||
|
||
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 sys
|
||
import logging
|
||
import yaml # Keep if load_yaml_config needs it or for other reasons
|
||
|
||
# Adjust BASE_DIR calculation as needed based on where this file is relative to the project root
|
||
# Assuming install_desktop.py is in builder/core/, and project root is parent of builder/
|
||
BASE_DIR = os.path.dirname(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
|
||
# xbps_commands is likely not needed here as construct_xbps_install_args handles it internally
|
||
# from builder.core.xbps_commands import xbps_commands
|
||
# enable_services_in_chroot implementation might need checking/adaptation later
|
||
from builder.core.enable_services import enable_services_in_chroot
|
||
# paths is passed as argument, so not needed as direct import here
|
||
# from builder.core.bootstrap.paths import paths
|
||
from builder.core.config_loader import load_yaml_config # Needed to load desktop YAML
|
||
from builder.configs import logger_config
|
||
from builder.core import bootstrap # Import bootstrap module for construct_xbps_install_args
|
||
|
||
# Module-level logger setup
|
||
logger = logger_config.setup_logger('install_desktop')
|
||
except ImportError as e:
|
||
# 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 install_desktop: {e}. Ensure your environment is set up correctly.")
|
||
except Exception:
|
||
print(f"Error importing necessary modules for install_desktop: {e}. Ensure your environment is set up correctly.")
|
||
sys.exit(1)
|
||
|
||
|
||
# MODIFIED FUNCTION SIGNATURE to accept arguments passed from iso_builder_main
|
||
# Matching the order and names from the intended call
|
||
def install_desktop_environment(arch, desktop_environment_name, desktops_config, target_env='rootfs', paths=None, host_arch=None, repositories_data=None):
|
||
"""
|
||
Installs the specified desktop environment and enables associated services in the chroot system,
|
||
using the desktop configuration from the YAML, employing the host-execution strategy.
|
||
|
||
Args:
|
||
arch (str): Architecture (e.g., 'aarch64').
|
||
desktop_environment_name (str): Name of the desktop environment (e.g., 'xfce').
|
||
desktops_config (dict): Desktop configuration loaded from the YAML (desktops_config.yaml file).
|
||
This contains info about the desktop, including the path to its specific YAML.
|
||
target_env (str): Target environment to install the desktop ('rootfs'). Defaults to 'rootfs'.
|
||
paths (dict): Dictionary of build paths. Required to get target path and cache dir.
|
||
host_arch (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.info(f"=> Starting installation of desktop environment: {desktop_environment_name} in environment: {target_env} ({arch})...")
|
||
|
||
if paths is None or not isinstance(paths, dict):
|
||
logger.error("Paths dictionary is missing or incorrect.")
|
||
raise ValueError("Paths dictionary is required.")
|
||
|
||
if target_env == 'rootfs':
|
||
target_path = paths.get('ROOTFS')
|
||
else:
|
||
logger.error(f"Invalid target environment for desktop installation: {target_env}. Installation is only supported in ROOTFS.")
|
||
raise ValueError(f"Invalid target environment for desktop installation: {target_env}")
|
||
|
||
if not target_path:
|
||
logger.error(f"Path for environment '{target_env}' not found in paths dictionary.")
|
||
raise KeyError(f"Path for environment '{target_env}' not found.")
|
||
|
||
|
||
desktop_yaml_file = None
|
||
total_desktop_packages_list = []
|
||
services_to_enable_list = []
|
||
|
||
if desktops_config and 'desktops' in desktops_config and desktop_environment_name.lower() in desktops_config['desktops']:
|
||
desktop_info = desktops_config['desktops'][desktop_environment_name.lower()]
|
||
|
||
desktop_yaml_file = desktop_info.get('yaml_file')
|
||
else:
|
||
logger.error(f"Configuration for desktop environment '{desktop_environment_name}' not found in desktops_config.yaml.")
|
||
raise ValueError(f"Configuration for desktop environment '{desktop_environment_name}' not found.")
|
||
|
||
|
||
if desktop_yaml_file:
|
||
desktop_yaml_full_path = os.path.join(BASE_DIR, desktop_yaml_file)
|
||
logger.info(f"=> Loading desktop configuration from YAML file: {desktop_yaml_full_path}")
|
||
try:
|
||
desktop_packages_config = load_yaml_config(desktop_yaml_full_path, os.path.basename(desktop_yaml_full_path))
|
||
except Exception as e:
|
||
logger.error(f"Error loading desktop packages YAML '{desktop_yaml_full_path}': {e}")
|
||
raise
|
||
|
||
if desktop_packages_config:
|
||
logger.debug(f"=> Desktop YAML file loaded successfully from: {desktop_yaml_full_path}")
|
||
|
||
desktop_env_details = desktop_packages_config.get('desktop_environment', {})
|
||
|
||
if desktop_env_details:
|
||
logger.debug(f"=> Found 'desktop_environment' section in YAML.")
|
||
|
||
desktop_config_for_arch = desktop_env_details.get(arch, {})
|
||
|
||
if desktop_config_for_arch:
|
||
logger.debug(f"=> Configuration found for architecture: {arch} within 'desktop_environment' section.")
|
||
desktop_packages = desktop_config_for_arch.get('desktop_packages', [])
|
||
login_manager_packages = desktop_config_for_arch.get('login_manager_packages', [])
|
||
default_packages = desktop_config_for_arch.get('default_packages', [])
|
||
|
||
if isinstance(desktop_packages, list):
|
||
total_desktop_packages_list.extend(desktop_packages)
|
||
else:
|
||
logger.warning(f"'desktop_packages' for {arch} in {desktop_yaml_full_path} is not a list (under desktop_environment:{arch}). Ignoring.")
|
||
|
||
if isinstance(login_manager_packages, list):
|
||
total_desktop_packages_list.extend(login_manager_packages)
|
||
else:
|
||
logger.warning(f"'login_manager_packages' for {arch} in {desktop_yaml_full_path} is not a list (under desktop_environment:{arch}). Ignoring.")
|
||
|
||
if isinstance(default_packages, list):
|
||
total_desktop_packages_list.extend(default_packages)
|
||
else:
|
||
logger.warning(f"'default_packages' for {arch} in {desktop_yaml_full_path} is not a list (under desktop_environment:{arch}). Ignoring.")
|
||
|
||
services_to_enable_list = desktop_config_for_arch.get('services_enable', [])
|
||
if not isinstance(services_to_enable_list, list):
|
||
logger.warning(f"'services_enable' for {arch} in {desktop_yaml_full_path} is not a list (under desktop_environment:{arch}). Ignoring.")
|
||
services_to_enable_list = []
|
||
|
||
else:
|
||
logger.warning(f"No configuration found for architecture {arch} within 'desktop_environment' section in {desktop_yaml_full_path}. No desktop packages or services loaded.")
|
||
|
||
else:
|
||
logger.error(f"Could not find 'desktop_environment' section in {desktop_yaml_full_path}.")
|
||
|
||
else:
|
||
logger.error(f"=> Failed to load desktop YAML configuration from: {desktop_yaml_full_path}")
|
||
|
||
|
||
if total_desktop_packages_list:
|
||
logger.info(f"=> Desktop package list for {arch} extracted successfully. Building XBPS_INSTALL_CMD command...")
|
||
|
||
adapted_package_structure = {"rootfs": {arch: total_desktop_packages_list}}
|
||
|
||
desktop_packages_args = bootstrap.construct_xbps_install_args(
|
||
"rootfs",
|
||
paths,
|
||
arch,
|
||
repositories_data,
|
||
adapted_package_structure
|
||
)
|
||
|
||
if not desktop_packages_args:
|
||
logger.warning("Skipping desktop packages installation due to failure in constructing xbps-install arguments.")
|
||
else:
|
||
desktop_install_command = ["/usr/bin/xbps-install"] + desktop_packages_args
|
||
|
||
logger.info(f"Executing desktop packages installation command (host): {' '.join(desktop_install_command)}")
|
||
try:
|
||
run_command(desktop_install_command)
|
||
logger.info(f"=> Installation of desktop packages completed successfully in environment: {target_env}.")
|
||
except Exception as e:
|
||
logger.error(f"Error executing XBPS_INSTALL_CMD for desktop packages in environment: {target_env}: {e}")
|
||
raise
|
||
|
||
if services_to_enable_list:
|
||
logger.info("=> Services to enable found in the desktop YAML configuration.")
|
||
try:
|
||
enable_services_in_chroot(target_path, services_to_enable_list)
|
||
logger.info(f"=> Services specified in the desktop YAML enabled successfully in environment: {target_env}.")
|
||
except Exception as e:
|
||
logger.error(f"Error enabling services specified in the desktop YAML in environment: {target_env}: {e}")
|
||
raise
|
||
else:
|
||
logger.warning("=> No service list to enable found in the desktop YAML configuration. Skipping service activation.")
|
||
|
||
logger.info(f"=> Installation and configuration of desktop environment: {desktop_environment_name} ({target_env}) completed.")
|
||
logger.info(f"--------------------------------------------------------------------\n") |