#!/usr/bin/python3 import subprocess import tempfile import os from os.path import join, getsize import argparse from multiprocessing import Pool, cpu_count import shutil import sys # Set command line arguments parser = argparse.ArgumentParser( formatter_class=argparse.ArgumentDefaultsHelpFormatter) parser.add_argument("-b", "--build_dir", dest="BUILD_DIR", default="/home/ed/openbmc-openbmc", help="Build directory path.") parser.add_argument("-s", "--squashfs_file", dest="SQUASHFS_FILE", default="/build/tmp/deploy/images/wolfpass" + "/intel-platforms-wolfpass.squashfs-xz", help="Squashfs file.") parser.add_argument("-t", "--threads", dest="threads", default=int(cpu_count()), type=int, help="Number of threads to use (defaults to cpu count)") args = parser.parse_args() # files below this size wont be attempted FILE_SIZE_LIMIT = 0 SQUASHFS = args.SQUASHFS_FILE if not os.path.isabs(args.SQUASHFS_FILE): SQUASHFS = args.BUILD_DIR + args.SQUASHFS_FILE original_size = getsize(SQUASHFS) print("squashfs size: {}".format(original_size)) results = [] def get_unsquash_results(filepath): with tempfile.TemporaryDirectory() as newsquashfsroot: input_path = os.path.join(newsquashfsroot, "input") shutil.copytree(squashfsdir, input_path, symlinks=True, ignore_dangling_symlinks=True) file_to_remove = os.path.join(input_path, filepath) try: os.remove(file_to_remove) except IsADirectoryError: shutil.rmtree(file_to_remove) subprocess.check_output( ["mksquashfs", input_path, newsquashfsroot + "/test", "-comp", "xz", '-processors', '1']) return ((filepath.replace(squashfsdir, ""), original_size - getsize(newsquashfsroot + "/test"))) with tempfile.TemporaryDirectory() as tempsquashfsdir: print("writing to " + tempsquashfsdir) squashfsdir = os.path.join(tempsquashfsdir, "squashfs-root") #squashfsdir = os.path.join("/tmp", "squashfs-root") command = ["unsquashfs", "-d", squashfsdir, SQUASHFS] print(" ".join(command)) subprocess.check_call(command) files_to_test = [] for root, dirs, files in os.walk(squashfsdir): for name in files + dirs: filepath = os.path.join(root, name) if not os.path.islink(filepath): if getsize(filepath) > FILE_SIZE_LIMIT: files_to_test.append( os.path.relpath(filepath, squashfsdir)) print("{} files to attempt removing".format(len(files_to_test))) print("Using {} threads".format(args.threads)) with Pool(args.threads) as p: for i, res in enumerate(p.imap_unordered(get_unsquash_results, files_to_test)): results.append(res) sys.stderr.write('\rdone {:.1f}%'.format( 100 * (i/len(files_to_test)))) results.sort(key=lambda x: x[1], reverse=True) with open("results.txt", 'w') as result_file: for filepath, size in results: result = "{:>10}: {}".format(size, filepath) print(result) result_file.write(result + "\n")