Blame org_fedora_oscap/utils.py

Packit Service 39273c
#
Packit Service 39273c
# Copyright (C) 2013  Red Hat, Inc.
Packit Service 39273c
#
Packit Service 39273c
# This copyrighted material is made available to anyone wishing to use,
Packit Service 39273c
# modify, copy, or redistribute it subject to the terms and conditions of
Packit Service 39273c
# the GNU General Public License v.2, or (at your option) any later version.
Packit Service 39273c
# This program is distributed in the hope that it will be useful, but WITHOUT
Packit Service 39273c
# ANY WARRANTY expressed or implied, including the implied warranties of
Packit Service 39273c
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General
Packit Service 39273c
# Public License for more details.  You should have received a copy of the
Packit Service 39273c
# GNU General Public License along with this program; if not, write to the
Packit Service 39273c
# Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
Packit Service 39273c
# 02110-1301, USA.  Any Red Hat trademarks that are incorporated in the
Packit Service 39273c
# source code or documentation are not subject to the GNU General Public
Packit Service 39273c
# License and may only be used or replicated with the express permission of
Packit Service 39273c
# Red Hat, Inc.
Packit Service 39273c
#
Packit Service 39273c
# Red Hat Author(s): Vratislav Podzimek <vpodzime@redhat.com>
Packit Service 39273c
#
Packit Service 39273c
Packit Service 39273c
"""Module with various utility functions used by the addon."""
Packit Service 39273c
Packit Service 39273c
import os
Packit Service 39273c
import os.path
Packit Service 39273c
import shutil
Packit Service 39273c
import glob
Packit Service 39273c
import hashlib
Packit Service 39273c
Packit Service 39273c
Packit Service 39273c
def ensure_dir_exists(dirpath):
Packit Service 39273c
    """
Packit Service 39273c
    Checks if a given directory exists and if not, it creates the directory as
Packit Service 39273c
    well as all the nonexisting directories in its path.
Packit Service 39273c
Packit Service 39273c
    :param dirpath: path to the directory to be checked/created
Packit Service 39273c
    :type dirpath: str
Packit Service 39273c
Packit Service 39273c
    """
Packit Service 39273c
Packit Service 39273c
    if not dirpath:
Packit Service 39273c
        # nothing can be done for an empty string
Packit Service 39273c
        return
Packit Service 39273c
Packit Service 39273c
    if not os.path.isdir(dirpath):
Packit Service 39273c
        os.makedirs(dirpath)
Packit Service 39273c
Packit Service 39273c
Packit Service 39273c
def universal_copy(src, dst):
Packit Service 39273c
    """
Packit Service 39273c
    Function that copies the files or directories specified by the src argument
Packit Service 39273c
    to the destination given by the dst argument. It should follow the same
Packit Service 39273c
    rules as the standard 'cp' utility.
Packit Service 39273c
Packit Service 39273c
    :param src: source to copy -- may be a glob, file path or a directory path
Packit Service 39273c
    :type src: str
Packit Service 39273c
    :param dst: destination to copy to
Packit Service 39273c
    :type src: str
Packit Service 39273c
Packit Service 39273c
    """
Packit Service 39273c
Packit Service 39273c
    if glob.has_magic(src):
Packit Service 39273c
        # src is a glob
Packit Service 39273c
        sources = glob.glob(src)
Packit Service 39273c
    else:
Packit Service 39273c
        # not a glob
Packit Service 39273c
        sources = [src]
Packit Service 39273c
Packit Service 39273c
    for item in sources:
Packit Service 39273c
        if os.path.isdir(item):
Packit Service 39273c
            if os.path.isdir(dst):
Packit Service 39273c
                item = item.rstrip("/")
Packit Service 39273c
                dirname = item.rsplit("/", 1)[-1]
Packit Service 39273c
                shutil.copytree(item, join_paths(dst, dirname))
Packit Service 39273c
            else:
Packit Service 39273c
                shutil.copytree(item, dst)
Packit Service 39273c
        else:
Packit Service 39273c
            shutil.copy2(item, dst)
Packit Service 39273c
Packit Service 39273c
Packit Service 39273c
def keep_type_map(func, iterable):
Packit Service 39273c
    """
Packit Service 39273c
    Function that maps the given function to items in the given iterable
Packit Service 39273c
    keeping the type of the iterable.
Packit Service 39273c
Packit Service 39273c
    :param func: function to be mapped on the items in the iterable
Packit Service 39273c
    :type func: in_item -> out_item
Packit Service 39273c
    :param iterable: iterable providing the items the function should be mapped
Packit Service 39273c
                     on
Packit Service 39273c
    :type iterable: iterable
Packit Service 39273c
    :return: iterable providing items produced by the function mapped on the
Packit Service 39273c
             input items
Packit Service 39273c
    :rtype: the same type as input iterable or generator if the iterable is not
Packit Service 39273c
            of any basic Python types
Packit Service 39273c
Packit Service 39273c
    """
Packit Service 39273c
Packit Service 39273c
    if isinstance(iterable, dict):
Packit Service 39273c
        return dict((func(key), iterable[key]) for key in iterable)
Packit Service 39273c
Packit Service 39273c
    items_gen = (func(item) for item in iterable)
Packit Service 39273c
    if isinstance(iterable, list):
Packit Service 39273c
        return list(items_gen)
Packit Service 39273c
    elif isinstance(iterable, tuple):
Packit Service 39273c
        if iterable.__class__ is tuple:
Packit Service 39273c
            return tuple(items_gen)
Packit Service 39273c
        else:
Packit Service 39273c
            return iterable.__class__(*items_gen)
Packit Service 39273c
    elif isinstance(iterable, set):
Packit Service 39273c
        return set(items_gen)
Packit Service 39273c
    elif isinstance(iterable, str):
Packit Service 39273c
        return "".join(items_gen)
Packit Service 39273c
    else:
Packit Service 39273c
        return items_gen
Packit Service 39273c
Packit Service 39273c
Packit Service 39273c
def join_paths(path1, path2):
Packit Service 39273c
    """
Packit Service 39273c
    Joins two paths as one would expect -- i.e. just like the os.path.join
Packit Service 39273c
    function except for doing crazy things when the second argument is an
Packit Service 39273c
    absolute path.
Packit Service 39273c
Packit Service 39273c
    :param path1: first path
Packit Service 39273c
    :type path1: str
Packit Service 39273c
    :param path2: second path
Packit Service 39273c
    :type path2: str
Packit Service 39273c
    :return: path1 and path2 joined with the file separator
Packit Service 39273c
    :rtype: str
Packit Service 39273c
Packit Service 39273c
    """
Packit Service 39273c
Packit Service 39273c
    # os.path.normpath doesn't squash two starting slashes
Packit Service 39273c
    path1.replace("//", "/")
Packit Service 39273c
Packit Service 39273c
    return os.path.normpath(path1 + os.path.sep + path2)
Packit Service 39273c
Packit Service 39273c
Packit Service 39273c
def get_hashing_algorithm(fingerprint):
Packit Service 39273c
    """
Packit Service 39273c
    Get hashing algorithm for the given fingerprint or None if fingerprint of
Packit Service 39273c
    unsupported length is given.
Packit Service 39273c
Packit Service 39273c
    :param fingerprint: hexa fingerprint to get the hashing algorithm for
Packit Service 39273c
    :type fingerprint: hexadecimal str
Packit Service 39273c
    :return: one of the hashlib.* hash objects
Packit Service 39273c
    :rtype: hashlib.HASH object
Packit Service 39273c
Packit Service 39273c
    """
Packit Service 39273c
Packit Service 39273c
    hashes = (hashlib.md5(), hashlib.sha1(), hashlib.sha224(),
Packit Service 39273c
              hashlib.sha256(), hashlib.sha384(), hashlib.sha512())
Packit Service 39273c
Packit Service 39273c
    if len(fingerprint) % 2 == 1:
Packit Service 39273c
        return None
Packit Service 39273c
Packit Service 39273c
    num_bytes = len(fingerprint) / 2
Packit Service 39273c
Packit Service 39273c
    for hash_obj in hashes:
Packit Service 39273c
        # pylint: disable-msg=E1103
Packit Service 39273c
        if hash_obj.digest_size == num_bytes:
Packit Service 39273c
            return hash_obj
Packit Service 39273c
Packit Service 39273c
    return None
Packit Service 39273c
Packit Service 39273c
Packit Service 39273c
def get_file_fingerprint(fpath, hash_obj):
Packit Service 39273c
    """
Packit Service 39273c
    Get fingerprint of the given file with the given hashing algorithm.
Packit Service 39273c
Packit Service 39273c
    :param fpath: path to the file to get fingerprint for
Packit Service 39273c
    :type fpath: str
Packit Service 39273c
    :param hash_obj: hashing algorithm to get fingerprint with
Packit Service 39273c
    :type hash_obj: hashlib.HASH
Packit Service 39273c
    :return: fingerprint of the given file with the given algorithm
Packit Service 39273c
    :rtype: hexadecimal str
Packit Service 39273c
Packit Service 39273c
    """
Packit Service 39273c
Packit Service 39273c
    with open(fpath, "rb") as fobj:
Packit Service 39273c
        bsize = 4 * 1024
Packit Service 39273c
        # process file as 4 KB blocks
Packit Service 39273c
        buf = fobj.read(bsize)
Packit Service 39273c
        while buf:
Packit Service 39273c
            hash_obj.update(buf)
Packit Service 39273c
            buf = fobj.read(bsize)
Packit Service 39273c
Packit Service 39273c
    return hash_obj.hexdigest()