diff --git a/dfvfs/vfs/lvm_file_entry.py b/dfvfs/vfs/lvm_file_entry.py index f900d97a..c5564d5e 100644 --- a/dfvfs/vfs/lvm_file_entry.py +++ b/dfvfs/vfs/lvm_file_entry.py @@ -10,20 +10,19 @@ from dfvfs.lib import lvm from dfvfs.path import lvm_path_spec from dfvfs.vfs import file_entry -from dfvfs.vfs import vfs_stat class LVMDirectory(file_entry.Directory): - """Class that implements a directory object using pyvslvm.""" + """File system directory that uses pyvslvm.""" def _EntriesGenerator(self): """Retrieves directory entries. - Since a directory can contain a vast number of entries using - a generator is more memory efficient. + Since a directory can contain a vast number of entries using + a generator is more memory efficient. Yields: - A path specification (instance of PathSpec). + LVMPathSpec: a path specification. """ # Only the virtual root file has directory entries. volume_index = getattr(self.path_spec, 'volume_index', None) @@ -43,93 +42,71 @@ def _EntriesGenerator(self): class LVMFileEntry(file_entry.FileEntry): - """Class that implements a file entry object using pyvslvm.""" + """File system file entry that uses pyvslvm.""" TYPE_INDICATOR = definitions.TYPE_INDICATOR_LVM def __init__( self, resolver_context, file_system, path_spec, is_root=False, - is_virtual=False): - """Initializes the file entry object. + is_virtual=False, vslvm_logical_volume=None): + """Initializes a file entry. Args: - resolver_context: the resolver context (instance of resolver.Context). - file_system: the file system object (instance of FileSystem). - path_spec: the path specification (instance of PathSpec). - is_root: optional boolean value to indicate if the file entry is - the root file entry of the corresponding file system. - is_virtual: optional boolean value to indicate if the file entry is - a virtual file entry emulated by the corresponding file - system. + resolver_context (Context): resolver context. + file_system (FileSystem): file system. + path_spec (PathSpec): path specification. + is_root (Optional[bool]): True if the file entry is the root file entry + of the corresponding file system. + is_virtual (Optional[bool]): True if the file entry is a virtual file + vslvm_logical_volume (Optional[pyvslvm.logical_volume]): a LVM logical + volume. """ + if not is_virtual and vslvm_logical_volume is None: + vslvm_logical_volume = file_system.GetLVMLogicalVolumeByPathSpec( + path_spec) + if not is_virtual and vslvm_logical_volume is None: + raise errors.BackEndError( + u'Missing vslvm logical volume in non-virtual file entry.') + super(LVMFileEntry, self).__init__( resolver_context, file_system, path_spec, is_root=is_root, is_virtual=is_virtual) self._name = None + self._vslvm_logical_volume = vslvm_logical_volume + + if self._is_virtual: + self._type = definitions.FILE_ENTRY_TYPE_DIRECTORY + else: + self._type = definitions.FILE_ENTRY_TYPE_FILE def _GetDirectory(self): """Retrieves the directory. Returns: - A directory object (instance of Directory) or None. + LVMDirectory: a directory or None if not available. """ - if self._stat_object is None: - self._stat_object = self._GetStat() - - if (self._stat_object and - self._stat_object.type == self._stat_object.TYPE_DIRECTORY): + if self._type == definitions.FILE_ENTRY_TYPE_DIRECTORY: return LVMDirectory(self._file_system, self.path_spec) - return def _GetStat(self): - """Retrieves the stat object. + """Retrieves information about the file entry. Returns: - The stat object (instance of VFSStat). - - Raises: - BackEndError: when the vslvm logical volume is missing in a non-virtual - file entry. + VFSStat: a stat object. """ - vslvm_logical_volume = self.GetLVMLogicalVolume() - if not self._is_virtual and vslvm_logical_volume is None: - raise errors.BackEndError( - 'Missing vslvm logical volume in non-virtual file entry.') - - stat_object = vfs_stat.VFSStat() - - # File data stat information. - if vslvm_logical_volume is not None: - stat_object.size = vslvm_logical_volume.size - - # Date and time stat information. - if vslvm_logical_volume is not None: - # TODO: implement in pyvslvm - # timestamp = vslvm_logical_volume.get_creation_time_as_integer() - timestamp = None - if timestamp is not None: - date_time_values = dfdatetime_posix_time.PosixTime(timestamp) + stat_object = super(LVMFileEntry, self)._GetStat() - stat_time, stat_time_nano = date_time_values.CopyToStatTimeTuple() - if stat_time is not None: - stat_object.crtime = stat_time - stat_object.crtime_nano = stat_time_nano - - # Ownership and permissions stat information. - - # File entry type stat information. - - # The root file entry is virtual and should have type directory. - if self._is_virtual: - stat_object.type = stat_object.TYPE_DIRECTORY - else: - stat_object.type = stat_object.TYPE_FILE + if self._vslvm_logical_volume is not None: + stat_object.size = self._vslvm_logical_volume.size return stat_object + # TODO: implement creation_time property after implementing + # vslvm_logical_volume.get_creation_time_as_integer() + @property def name(self): - """The name of the file entry, which does not include the full path.""" + """str: name of the file entry, without the full path.""" if self._name is None: location = getattr(self.path_spec, 'location', None) if location is not None: @@ -144,7 +121,7 @@ def name(self): @property def sub_file_entries(self): - """The sub file entries (generator of instance of FileEntry).""" + """generator[LVMFileEntry]: sub file entries.""" if self._directory is None: self._directory = self._GetDirectory() @@ -153,23 +130,18 @@ def sub_file_entries(self): yield LVMFileEntry(self._resolver_context, self._file_system, path_spec) def GetLVMLogicalVolume(self): - """Retrieves the LVM logical volume object. + """Retrieves the LVM logical volume. Returns: - A LVM logical volume object (instance of pyvslvm.logical_volume). + pyvslvm.logical_volume: a LVM logical volume. """ - volume_index = lvm.LVMPathSpecGetVolumeIndex(self.path_spec) - if volume_index is None: - return - - vslvm_volume_group = self._file_system.GetLVMVolumeGroup() - return vslvm_volume_group.get_logical_volume(volume_index) + return self._vslvm_logical_volume def GetParentFileEntry(self): """Retrieves the parent file entry. Returns: - The parent file entry object (instance of FileEntry) or None. + LVMFileEntry: parent file entry or Noneif not available. """ volume_index = lvm.LVMPathSpecGetVolumeIndex(self.path_spec) if volume_index is None: diff --git a/dfvfs/vfs/lvm_file_system.py b/dfvfs/vfs/lvm_file_system.py index a9667d9d..049b7f02 100644 --- a/dfvfs/vfs/lvm_file_system.py +++ b/dfvfs/vfs/lvm_file_system.py @@ -17,15 +17,15 @@ class LVMFileSystem(file_system.FileSystem): - """Class that implements a file system object using pyvslvm.""" + """File system that uses pyvslvm.""" TYPE_INDICATOR = definitions.TYPE_INDICATOR_LVM def __init__(self, resolver_context): - """Initializes a file system object. + """Initializes a file system. Args: - resolver_context: the resolver context (instance of Context). + resolver_context (Context): resolver context. """ super(LVMFileSystem, self).__init__(resolver_context) self._file_object = None @@ -49,8 +49,8 @@ def _Open(self, path_spec, mode='rb'): """Opens the file system object defined by path specification. Args: - path_spec: a path specification (instance of PathSpec). - mode: optional file access mode. The default is 'rb' read-only binary. + path_spec (PathSpec): path specification. + mode (Optional[str]): file access mode. Raises: AccessError: if the access to open the file was denied. @@ -84,10 +84,10 @@ def FileEntryExistsByPathSpec(self, path_spec): """Determines if a file entry for a path specification exists. Args: - path_spec: a path specification (instance of PathSpec). + path_spec (PathSpec): path specification. Returns: - Boolean indicating if the file entry exists. + bool: True if the file entry exists. """ volume_index = lvm.LVMPathSpecGetVolumeIndex(path_spec) @@ -104,10 +104,10 @@ def GetFileEntryByPathSpec(self, path_spec): """Retrieves a file entry for a path specification. Args: - path_spec: a path specification (instance of PathSpec). + path_spec (PathSpec): path specification. Returns: - A file entry (instance of FileEntry) or None. + LVMFileEntry: a file entry or None if not available. """ volume_index = lvm.LVMPathSpecGetVolumeIndex(path_spec) @@ -127,11 +127,24 @@ def GetFileEntryByPathSpec(self, path_spec): return dfvfs.vfs.lvm_file_entry.LVMFileEntry( self._resolver_context, self, path_spec) + def GetLVMLogicalVolumeByPathSpec(self, path_spec): + """Retrieves a LVM logical volume for a path specification. + + Args: + path_spec (PathSpec): path specification. + + Returns: + pyvslvm.logical_volume: a LVM logical volume or None if not available. + """ + volume_index = lvm.LVMPathSpecGetVolumeIndex(path_spec) + if volume_index is not None: + return self._vslvm_volume_group.get_logical_volume(volume_index) + def GetLVMVolumeGroup(self): - """Retrieves the LVM volume group object. + """Retrieves the LVM volume group. Returns: - The LVM handle object (instance of pyvslvm.volume_group). + pyvslvm.volume_group: a LVM volume group. """ return self._vslvm_volume_group @@ -139,7 +152,7 @@ def GetRootFileEntry(self): """Retrieves the root file entry. Returns: - A file entry (instance of FileEntry). + LVMFileEntry: root file entry or None if not available. """ path_spec = lvm_path_spec.LVMPathSpec( location=self.LOCATION_ROOT, parent=self._path_spec.parent) diff --git a/tests/vfs/lvm_file_entry.py b/tests/vfs/lvm_file_entry.py index 56ec1714..6226c561 100644 --- a/tests/vfs/lvm_file_entry.py +++ b/tests/vfs/lvm_file_entry.py @@ -79,7 +79,8 @@ def tearDown(self): def testIntialize(self): """Test the __init__ function.""" file_entry = lvm_file_entry.LVMFileEntry( - self._resolver_context, self._file_system, self._lvm_path_spec) + self._resolver_context, self._file_system, self._lvm_path_spec, + is_virtual=True) self.assertIsNotNone(file_entry)