Source code for parted.filesys

# Copyright (c) 2023 Adolfo Gómez
#
# Permission is hereby granted, free of charge, to any person obtaining a copy
# of this software and associated documentation files (the "Software"), to deal
# in the Software without restriction, including without limitation the rights
# to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
# copies of the Software, and to permit persons to whom the Software is
# furnished to do so, subject to the following conditions:
#
# The above copyright notice and this permission notice shall be included in all
# copies or substantial portions of the Software.
#
# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
# AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
# LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
# OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
# SOFTWARE.

"""
This module contains Filesystem related classes and functions

:author: Adolfo Gómez, dkmaster at dkmon dot com
"""

from os import stat
import typing
import enum
import logging

from parted.exceptions import PartedException

from . import _parted  # type: ignore
from . import geom

from .util import make_destroyable

if typing.TYPE_CHECKING:
    import cffi
    from . import timer

logger = logging.getLogger(__name__)


[docs]class FileSystemType: """This class represents a FileSystem """ _filesystemtype: typing.Any = None # Well know filesystems, some of them, all supported by parted
[docs] class WNT(enum.Enum): """Well known filesystems identifiers in parted This class contains the well known filesystems identifiers in parted. """ zfs = 'zfs' udf = 'udf' btrfs = 'btrfs' nilfs2 = 'nilfs2' ext2 = 'ext2' ext3 = 'ext3' ext4 = 'ext4' fat16 = 'fat16' fat32 = 'fat32' hfs = 'hfs' hfsplus = 'hfs+' hfsx = 'hfsx' jfs = 'jfs' swsusp = 'swsusp' linux_swap = 'linux-swap' linux_swap_v0 = 'linux-swap(v0)' linux_swap_v1 = 'linux-swap(v1)' ntfs = 'ntfs' reiserfs = 'reiserfs' freebsd_ufs = 'freebsd-ufs' hp_ufs = 'hp-ufs' sun_ufs = 'sun-ufs' xfs = 'xfs' apfs1 = 'apfs1' apfs2 = 'apfs2' asfs = 'asfs' amufs0 = 'amufs0' amufs1 = 'amufs1' amufs2 = 'amufs2' amufs3 = 'amufs3' amufs4 = 'amufs4' amufs5 = 'amufs5' affs0 = 'affs0' affs1 = 'affs1' affs2 = 'affs2' affs3 = 'affs3' affs4 = 'affs4' affs5 = 'affs5' affs6 = 'affs6'
[docs] @staticmethod def from_string(name: str) -> 'FileSystemType.WNT': """Returns a well known filesystem type from its name Args: name (str): Name of the filesystem type Returns: FileSystemType.WNT: The filesystem type Raises: ValueError: If the filesystem type is not known """ return FileSystemType.WNT.__members__[name]
def __str__(self): return self.value
def __init__(self, filesystemtype: typing.Union[WNT, str, 'cffi.FFI.CData', None] = None) -> None: """Creates a new FileSystemType object Args: filesystemtype (typing.Union[WNF, str, cffi.FFI.CData], optional): The filesystem type to create. Defaults to None. If None, a "nil" filesystem type is created, which is not valid, but can be used to iterate over all filesystem types or to compare with other filesystem types. """ if isinstance(filesystemtype, (str, FileSystemType.WNT)): fst = str(filesystemtype) self._filesystemtype = _parted.lib.ped_file_system_type_get(fst.encode()) else: self._filesystemtype = filesystemtype if filesystemtype else _parted.ffi.NULL def __bool__(self) -> bool: return bool(self._filesystemtype) def __eq__(self, other: typing.Any) -> bool: """Compares against another FileSystemType, string or WNF Args: other (typing.Any): The other object to compare against Returns: bool: True if both are related to same Filesystem, False otherwise """ if isinstance(other, FileSystemType): return self._filesystemtype == other._filesystemtype elif isinstance(other, FileSystemType.WNT): return self.name == other.value elif isinstance(other, str): return self.name == other else: return False @property def obj(self) -> 'cffi.FFI.CData': """Wrapped ``PedFileSystemType*`` object""" return self._filesystemtype @property def name(self) -> str: """Name of the filesystem (i.e. ext4, fat32, etc)""" if not self._filesystemtype: return '' return _parted.ffi.string(self._filesystemtype.name).decode()
[docs] def next(self) -> 'FileSystemType': """Returns the next filesystem type Returns: FileSystemType: The next filesystem type """ fs = self._filesystemtype if self._filesystemtype else _parted.ffi.NULL return FileSystemType(_parted.lib.ped_file_system_type_get_next(fs))
[docs] @staticmethod def enumerate() -> typing.Iterator['FileSystemType']: """Enumerates all filesystem types Yields: FileSystemType: Available valid filesystem types """ fs = _parted.ffi.NULL while True: fs = _parted.lib.ped_file_system_type_get_next(fs) if not fs: break yield FileSystemType(fs)
[docs] @staticmethod def from_string(name: str) -> 'FileSystemType': """Returns a filesystem type from its name Args: name (str): Name of the filesystem type Returns: FileSystemType: The filesystem type """ return FileSystemType(name)
[docs] @staticmethod def none() -> 'FileSystemType': """Returns the "nil" filesystem type Returns: FileSystemType: The "nil" filesystem type """ return FileSystemType()
def __str__(self) -> str: return self.name
[docs]class FileSystem: """This class represents a FileSystem""" _filesystem: typing.Any def __init__(self, filesystem: typing.Optional['cffi.FFI.CData'] = None): """Creates a new FileSystem object Args: filesystem (cffi.FFI.CData, optional): The filesystem to create. Defaults to None. If None, a "nil" filesystem is created, which is not valid, but can be used to iterate over all filesystems or to compare with other filesystems. """ self._filesystem = filesystem if filesystem else _parted.ffi.NULL def __bool__(self) -> bool: return bool(self._filesystem) @property def obj(self) -> 'cffi.FFI.CData': """Wrapped ``PedFileSystem*`` object""" return self._filesystem @property def geometry(self) -> 'geom.Geometry': """Geometry of the filesystem""" return geom.Geometry(self._filesystem.geom) @property def type(self) -> 'FileSystemType': """Type of the filesystem""" return FileSystemType(self._filesystem.type) @property def checked(self) -> bool: """Whether the filesystem has been checked""" return bool(self._filesystem.checked)
[docs] @staticmethod def probe(gometry: 'geom.Geometry') -> 'FileSystemType': """Probes the file system on the given geometry. Args: geometry (geom.Geometry): The geometry to probe Returns: FileSystemType: The filesystem type. If no filesystem is found, returns "nil" FileSystemType """ if not gometry: raise PartedException('Invalid geometry') return FileSystemType(_parted.lib.ped_file_system_probe(gometry.obj))
[docs] @staticmethod def probe_specific( gometry: 'geom.Geometry', fstype: typing.Union['FileSystemType.WNT', 'FileSystemType'] ) -> 'geom.Geometry': """Probes the file system on the given geometry. Args: geometry (geom.Geometry): The geometry to probe fstype (typing.Union[FileSystemType.WNT, FileSystemType]): The filesystem type to probe Returns: geom.Geometry: The geometry of the filesystem. If no filesystem is found, returns "nil" Geometry """ if isinstance(fstype, FileSystemType.WNT): fstype = FileSystemType(fstype) return make_destroyable(geom.Geometry(_parted.lib.ped_file_system_probe_specific(fstype.obj, gometry.obj)))