Source code for eb_staged_rebuild.livecheck

"""A before/after content record of a live install directory."""

import hashlib
import os

from eb_staged_rebuild.paths import lstat_kind

HASH_BLOCK_BYTES = 1024 * 1024


def _sha256(path):
    digest = hashlib.sha256()
    with open(path, "rb") as handle:
        while True:
            block = handle.read(HASH_BLOCK_BYTES)
            if not block:
                break
            digest.update(block)
    return digest.hexdigest()


[docs] def snapshot(path): path = os.fspath(path) kind = lstat_kind(path) if kind == "missing": return {"exists": False} if kind == "symlink": return {"exists": True, "symlink": True, "target": os.readlink(path)} if kind != "dir": return {"exists": True, "symlink": False, "kind": kind} st = os.lstat(path) rows = [] for dirpath, dirnames, filenames in os.walk(path, followlinks=False): kept = [] for name in dirnames: child = os.path.join(dirpath, name) if os.path.islink(child): lst = os.lstat(child) rows.append( [ os.path.relpath(child, path), "symlink", lst.st_ino, lst.st_size, os.readlink(child), ] ) else: kept.append(name) dirnames[:] = kept for name in filenames: child = os.path.join(dirpath, name) lst = os.lstat(child) kind_name = "symlink" if os.path.islink(child) else "file" detail = os.readlink(child) if kind_name == "symlink" else _sha256(child) rows.append( [ os.path.relpath(child, path), kind_name, lst.st_ino, lst.st_size, detail, ] ) rows.sort() return { "exists": True, "symlink": False, "kind": "dir", "inode": st.st_ino, "device": st.st_dev, "entries": rows, }
[docs] def same_snapshot(before, after): return before == after
[docs] def empty_real_dir(path): if lstat_kind(path) != "dir": return False return not os.listdir(path)