File: //var/opt/nydus/ops/customer_local_ops/operating_system/file_info.py
from datetime import datetime
import logging
from pathlib import Path
from typing import Any, Dict
from customer_local_ops.util.execute import runCommand
LOG = logging.getLogger(__name__)
class FileInfo:
def __init__(self, file_path: str):
self.path = Path(file_path)
self.__exists = False
self.__md5 = None
self.__sha1 = None
self.__sha256 = None
self.__access = None
self.__modify = None
self.__change = None
self.__fetch_file_info()
def __fetch_file_info(self):
if self.path.exists():
self.__exists = True
if self.__exists:
for hash_type in ['md5', 'sha1', 'sha256']:
try:
hash_value = self._get_file_hash(str(self.path), hash_type)
setattr(self, '_{}__{}'.format(self.__class__.__name__, hash_type), hash_value)
except RuntimeError:
continue
try:
timestamps = self._get_file_timestamps(str(self.path))
except (RuntimeError, IOError, OSError) as ex:
LOG.error("Failed to get timestamps for file %s: %s", self.path, str(ex))
self.__access = timestamps['access']
self.__modify = timestamps['modify']
self.__change = timestamps['change']
def to_dict(self):
return {
'exists': self.__exists,
'md5': self.__md5,
'sha1': self.__sha1,
'sha256': self.__sha256,
'access': self.__access,
'modify': self.__modify,
'change': self.__change,
}
def _get_file_hash(self, path: str, hash_type: str) -> str:
"""
Get the hash for a given filepath and hash type, e.g. md5, sha1, sha256
:param path: The path of the file to be hashed
:param hash_type: The type of hash to perform
:return: The hashed file as a string
"""
command = hash_type + 'sum'
exit_code, outs, errs = runCommand(
[command, path],
"{hash_type} file".format(hash_type=hash_type))
if exit_code != 0:
LOG.error("Failed to %s hash file %s: %s (%s)", hash_type, path, outs, errs)
raise RuntimeError("Failed to %s hash file %s: %s (%s)" % (hash_type, path, outs, errs))
# outputs 'hash filename'
outs_list = outs.split(" ")
return outs_list[0].strip()
def _get_file_timestamps(self, path: str) -> Dict[str, Any]:
"""
Get the access, modify and change date and time of given file path
:param path: The path of the file
:return: Dict containing access, modify and change timestamps in format YYYY-MM-DD HH:MM:SS.xxxxxxxx TZ_OFFSET
"""
file_path = Path(path)
access_time = datetime.fromtimestamp(file_path.stat().st_atime)
modify_time = datetime.fromtimestamp(file_path.stat().st_mtime)
change_time = datetime.fromtimestamp(file_path.stat().st_ctime)
file_timestamps = {"access": str(access_time),
"modify": str(modify_time),
"change": str(change_time)}
return file_timestamps