Skip to content

squashfs.py

ofrak_components.squashfs

SquashfsFilesystem (GenericBinary, FilesystemRoot) dataclass

Filesystem stored in a squashfs format.

SquashfsPacker (Packer)

Pack files into a compressed squashfs filesystem.

pack(self, resource, config=None) async

Pack the given resource.

Users should not call this method directly; rather, they should run Resource.run or Resource.pack.

Parameters:

Name Type Description Default
resource Resource required
config

Optional config for packing. If an implementation provides a default, this default will always be used when config would otherwise be None. Note that a copy of the default config will be passed, so the default config values cannot be modified persistently by a component run.

None
Source code in ofrak_components/squashfs.py
async def pack(self, resource: Resource, config=None):
    squashfs_view: SquashfsFilesystem = await resource.view_as(SquashfsFilesystem)
    temp_flush_dir = await squashfs_view.flush_to_disk()
    with tempfile.NamedTemporaryFile(suffix=".sqsh", mode="rb") as temp:
        command = ["mksquashfs", temp_flush_dir, temp.name, "-noappend"]
        subprocess.run(command, check=True, capture_output=True)
        new_data = temp.read()
        # Passing in the original range effectively replaces the original data with the new data
        resource.queue_patch(Range(0, await resource.get_data_length()), new_data)

SquashfsUnpacker (Unpacker)

Unpack a SquashFS filesystem.

unpack(self, resource, config=None) async

Unpack the given resource.

Users should not call this method directly; rather, they should run Resource.run or Resource.unpack.

Parameters:

Name Type Description Default
resource Resource

The resource that is being unpacked

required
config

Optional config for unpacking. If an implementation provides a default, this default will always be used when config would otherwise be None. Note that a copy of the default config will be passed, so the default config values cannot be modified persistently by a component run.

None
Source code in ofrak_components/squashfs.py
async def unpack(self, resource: Resource, config=None):
    with tempfile.NamedTemporaryFile() as temp_file:
        resource_data = await resource.get_data()
        temp_file.write(resource_data)
        temp_file.flush()

        with tempfile.TemporaryDirectory() as temp_flush_dir:
            command = [
                "unsquashfs",
                "-no-exit-code",  # Don't return failure status code on warnings
                "-force",  # Overwrite files that already exist
                "-dest",
                temp_flush_dir,
                temp_file.name,
            ]
            subprocess.run(command, check=True, capture_output=True)

            squashfs_view = await resource.view_as(SquashfsFilesystem)
            await squashfs_view.initialize_from_disk(temp_flush_dir)

_UnsquashfsV45Tool (ComponentExternalTool) private

__init__(self) special

Initialize self. See help(type(self)) for accurate signature.

Source code in ofrak_components/squashfs.py
def __init__(self):
    super().__init__("unsquashfs", "https://github.com/plougher/squashfs-tools.git", "")

is_tool_installed(self)

Check if a tool is installed by running it with the install_check_arg. This method runs <tool> <install_check_arg>.

Returns:

Type Description
bool

True if the tool command returned zero, False if tool could not be found or returned non-zero exit code.

Source code in ofrak_components/squashfs.py
def is_tool_installed(self) -> bool:
    try:
        result = subprocess.run(
            ["unsquashfs", "-help"],
            stdout=subprocess.PIPE,
            stderr=subprocess.DEVNULL,
        )
    except FileNotFoundError:
        return False

    if 0 != result.returncode:
        return False

    if b"-no-exit" not in result.stdout:
        # Version 4.5+ has the required -no-exit option
        return False

    return True