This repository has been archived on 2020-03-24. You can view files and clone it, but cannot push or open issues or pull requests.
quay/util/registry/changes.py
2015-08-07 11:56:38 -04:00

77 lines
2 KiB
Python

import marisa_trie
import os
import util.vendor.paxtarfile as tarfile
from util.registry.aufs import is_aufs_metadata, get_deleted_prefix
ALLOWED_TYPES = {tarfile.REGTYPE, tarfile.AREGTYPE}
def files_and_dirs_from_tar(source_stream, removed_prefix_collector):
try:
tar_stream = tarfile.open(mode='r|*', fileobj=source_stream)
except tarfile.ReadError:
# Empty tar file
return
for tar_info in tar_stream:
absolute = os.path.relpath(tar_info.name.decode('utf-8'), './')
# Skip metadata.
if is_aufs_metadata(absolute):
continue
# Add prefixes of removed paths to the collector.
deleted_prefix = get_deleted_prefix(absolute)
if deleted_prefix is not None:
removed_prefix_collector.add(deleted_prefix)
continue
# Otherwise, yield the path if it is in the allowed types.
if tar_info.type in ALLOWED_TYPES:
yield '/' + absolute
def __compute_removed(base_trie, removed_prefixes):
for prefix in removed_prefixes:
for filename in base_trie.keys(prefix):
yield filename
def __compute_added_changed(base_trie, delta_trie):
added = set()
changed = set()
for filename in delta_trie.keys():
if filename not in base_trie:
added.add(filename)
else:
changed.add(filename)
return added, changed
def __new_fs(base_trie, added, removed):
for filename in base_trie.keys():
if filename not in removed:
yield filename
for filename in added:
yield filename
def empty_fs():
return marisa_trie.Trie()
def compute_new_diffs_and_fs(base_trie, filename_source,
removed_prefix_collector):
new_trie = marisa_trie.Trie(filename_source)
(new_added, new_changed) = __compute_added_changed(base_trie, new_trie)
new_removed = marisa_trie.Trie(__compute_removed(base_trie,
removed_prefix_collector))
new_fs = marisa_trie.Trie(__new_fs(base_trie, new_added, new_removed))
return (new_fs, new_added, new_changed, new_removed.keys())