builder_peppermint_void/builder/core/squashfs.py
2025-04-26 12:01:44 +00:00

131 lines
5.1 KiB
Python

# -*- coding: utf-8 -*-
"""
SPDX-FileCopyrightText: 2023-2025 PeppermintOS Team
(peppermintosteam@proton.me)
SPDX-License-Identifier: GPL-3.0-or-later
This module is responsible for creating a SquashFS image from the root filesystem directory.
It utilizes the `mksquashfs` utility found within the PEPHOSTDIR to generate a compressed
read-only filesystem image that will be used in the PeppermintOS ISO.
The module handles the process of determining the required size, creating a temporary ext3 filesystem,
copying the root filesystem to it, unmounting, and then using `mksquashfs` to create the final image.
Temporary directories are cleaned up after the process is complete.
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 subprocess
import logging
import os
import sys
import tempfile
import shutil
BASE_DIR = os.path.dirname(os.path.dirname(os.path.abspath(__file__)))
sys.path.insert(0, BASE_DIR)
try:
from builder.core.bootstrap.paths import paths
from builder.core.command_runner import run_command
from builder.configs import logger_config
logger = logger_config.setup_logger('squashfs') # Pass the 'squashfs' argument
except ImportError as e:
print(f"Error importing necessary modules: {e}. Ensure your environment is set up correctly.")
sys.exit(1)
def create_squashfs_image(rootfs_dir, squashfs_output_file, pep_host_dir, logger):
"""
Initiates the creation of the SquashFS image using mksquashfs from PEPHOSTDIR.
Args:
rootfs_dir (str): The path to the root filesystem directory.
squashfs_output_file (str): The desired path for the output SquashFS image file.
pep_host_dir (str): The path to the PEPHOSTDIR, which should contain the mksquashfs utility.
logger (logging.Logger): The logger instance to use for logging messages.
Returns:
str or None: The path to the created SquashFS image file if successful, otherwise None.
"""
logger.info("=> Initiating SquashFS image creation using mksquashfs from PEPHOSTDIR...")
logger.info(f"=> Source ROOTFS directory: {rootfs_dir}")
logger.info(f"=> Output SquashFS file: {squashfs_output_file}")
logger.info(f"=> PEPHOSTDIR: {pep_host_dir}")
build_dir = paths['BUILDDIR']
image_dir = paths['IMAGEDIR']
liveos_tmp_dir = os.path.join(build_dir, "tmp", "LiveOS")
temp_rootfs_mount_dir = os.path.join(build_dir, "tmp-rootfs")
os.makedirs(liveos_tmp_dir, exist_ok=True)
os.makedirs(temp_rootfs_mount_dir, exist_ok=True)
try:
# Find out required size for the rootfs
rootfs_size_command = ["du", "--apparent-size", "-sm", rootfs_dir]
result = run_command(rootfs_size_command)
if result.returncode != 0:
logger.error(f"Error getting ROOTFS size: {result.stderr.strip()}")
return None
rootfs_size_mb = int(result.stdout.split()[0])
ext3_image_size_mb = 2 * rootfs_size_mb # Double the size
ext3_image_file = os.path.join(liveos_tmp_dir, "ext3fs.img")
truncate_command = ["truncate", "-s", f"{ext3_image_size_mb}M", ext3_image_file]
run_command(truncate_command)
mkfs_command = ["mkfs.ext3", "-F", "-m1", ext3_image_file]
run_command(mkfs_command)
mount_command = ["mount", "-o", "loop", ext3_image_file, temp_rootfs_mount_dir]
run_command(mount_command)
copy_command = ["cp", "-a", f"{rootfs_dir}/.", temp_rootfs_mount_dir]
run_command(copy_command)
umount_command = ["umount", "-f", temp_rootfs_mount_dir]
run_command(umount_command)
output_dir = os.path.dirname(squashfs_output_file)
os.makedirs(output_dir, exist_ok=True)
mksquashfs_command = [
"xbps-uchroot",
pep_host_dir,
"/usr/bin/mksquashfs",
os.path.join(build_dir, "tmp"),
squashfs_output_file,
"-comp", "zstd",
"-e19",
]
logger.info(f"=> Executing mksquashfs command: {' '.join(mksquashfs_command)}")
result = run_command(mksquashfs_command)
if result.returncode != 0:
logger.error(f"Error creating SquashFS image: {result.stderr.strip()}")
return None
chmod_command = ["chmod", "444", squashfs_output_file]
run_command(chmod_command)
return squashfs_output_file
except Exception as e:
logger.error(f"Unexpected error while creating SquashFS image: {e}")
return None
finally:
# Cleanup temporary directories
if os.path.exists(temp_rootfs_mount_dir):
shutil.rmtree(temp_rootfs_mount_dir, ignore_errors=True)
if os.path.exists(os.path.join(build_dir, "tmp")):
shutil.rmtree(os.path.join(build_dir, "tmp"), ignore_errors=True)
if os.path.exists(os.path.join(image_dir, "rootfs")):
shutil.rmtree(os.path.join(image_dir, "rootfs"), ignore_errors=True)