1 # Utilities for python-based QEMU tests 2 # 3 # Copyright 2024 Red Hat, Inc. 4 # 5 # Authors: 6 # Thomas Huth <thuth@redhat.com> 7 # 8 # This work is licensed under the terms of the GNU GPL, version 2 or 9 # later. See the COPYING file in the top-level directory. 10 11 import gzip 12 import lzma 13 import os 14 import shutil 15 import subprocess 16 import tarfile 17 18 """ 19 Round up to next power of 2 20 """ 21 def pow2ceil(x): 22 return 1 if x == 0 else 2**(x - 1).bit_length() 23 24 def file_truncate(path, size): 25 if size != os.path.getsize(path): 26 with open(path, 'ab+') as fd: 27 fd.truncate(size) 28 29 """ 30 Expand file size to next power of 2 31 """ 32 def image_pow2ceil_expand(path): 33 size = os.path.getsize(path) 34 size_aligned = pow2ceil(size) 35 if size != size_aligned: 36 with open(path, 'ab+') as fd: 37 fd.truncate(size_aligned) 38 39 def archive_extract(archive, dest_dir, member=None): 40 with tarfile.open(archive) as tf: 41 if hasattr(tarfile, 'data_filter'): 42 tf.extraction_filter = getattr(tarfile, 'data_filter', 43 (lambda member, path: member)) 44 if member: 45 tf.extract(member=member, path=dest_dir) 46 else: 47 tf.extractall(path=dest_dir) 48 49 def gzip_uncompress(gz_path, output_path): 50 if os.path.exists(output_path): 51 return 52 with gzip.open(gz_path, 'rb') as gz_in: 53 try: 54 with open(output_path, 'wb') as raw_out: 55 shutil.copyfileobj(gz_in, raw_out) 56 except: 57 os.remove(output_path) 58 raise 59 60 def lzma_uncompress(xz_path, output_path): 61 if os.path.exists(output_path): 62 return 63 with lzma.open(xz_path, 'rb') as lzma_in: 64 try: 65 with open(output_path, 'wb') as raw_out: 66 shutil.copyfileobj(lzma_in, raw_out) 67 except: 68 os.remove(output_path) 69 raise 70 71 def cpio_extract(cpio_handle, output_path): 72 cwd = os.getcwd() 73 os.chdir(output_path) 74 subprocess.run(['cpio', '-i'], 75 input=cpio_handle.read(), 76 stderr=subprocess.DEVNULL) 77 os.chdir(cwd) 78