diff --git a/build/usr/bin/fix-apk b/build/usr/bin/fix-apk index f241563..20f1570 100755 --- a/build/usr/bin/fix-apk +++ b/build/usr/bin/fix-apk @@ -1,45 +1,94 @@ #!/usr/bin/python3 # -*- coding: utf-8 -*- +import argparse import os +import shutil import sys +import tarfile +import tempfile -def fix_installed(layers): - installed = [] - for layer in layers[:-1]: - try: - with open(os.path.join(layer, 'lib/apk/db/installed'), 'r') as f: - buffer = [] - for line in f: - if line.startswith('C:'): - buffer = ''.join(buffer) - if buffer not in installed: - installed.append(buffer) - buffer = [] - buffer.append(line) - buffer = ''.join(buffer) - if buffer not in installed: - installed.append(buffer) - except: - continue - os.makedirs(os.path.join(layers[-1], 'lib/apk/db'), 0o755, True) - with open(os.path.join(layers[-1], 'lib/apk/db/installed'), 'w') as f: - f.writelines(installed) +parser = argparse.ArgumentParser(description='APK database merge script') +parser.add_argument('layers', help='Path to LXC layers to be merged', nargs=argparse.REMAINDER) -def fix_world(layers): - world = [] - for layer in layers[:-1]: - try: - with open(os.path.join(layer, 'etc/apk/world'), 'r') as f: - for line in f: - if line not in world: - world.append(line) - except: - continue - os.makedirs(os.path.join(layers[-1], 'etc/apk'), 0o755, True) - with open(os.path.join(layers[-1], 'etc/apk/world'), 'w') as f: - f.writelines(world) +if len(sys.argv) < 2: + parser.print_usage() + sys.exit(1) +args = parser.parse_args() +layers = args.layers[::-1] -if __name__ == '__main__': - fix_installed(sys.argv[1:]) - fix_world(sys.argv[1:]) +# /etc/apk/world +world = [] +for layer in layers: + try: + with open(os.path.join(layer, 'etc/apk/world'), 'r') as f: + for line in f: + if line not in world: + world.append(line) + except: + continue +os.makedirs(os.path.join(layers[-1], 'etc/apk'), 0o755, True) +with open(os.path.join(layers[-1], 'etc/apk/world'), 'w') as f: + f.writelines(world) +os.chown(os.path.join(layers[-1], 'etc'), 100000, 100000) +os.chown(os.path.join(layers[-1], 'etc/apk'), 100000, 100000) +os.chown(os.path.join(layers[-1], 'etc/apk/world'), 100000, 100000) + +# /lib/apk/db/installed +installed = [] +for layer in layers: + try: + with open(os.path.join(layer, 'lib/apk/db/installed'), 'r') as f: + buffer = [] + for line in f: + if line.startswith('C:'): + buffer = ''.join(buffer) + if buffer not in installed: + installed.append(buffer) + buffer = [] + buffer.append(line) + buffer = ''.join(buffer) + if buffer not in installed: + installed.append(buffer) + except: + continue +os.makedirs(os.path.join(layers[-1], 'lib/apk/db'), 0o755, True) +with open(os.path.join(layers[-1], 'lib/apk/db/installed'), 'w') as f: + f.writelines(installed) +os.chown(os.path.join(layers[-1], 'lib'), 100000, 100000) +os.chown(os.path.join(layers[-1], 'lib/apk'), 100000, 100000) +os.chown(os.path.join(layers[-1], 'lib/apk/db'), 100000, 100000) +os.chown(os.path.join(layers[-1], 'lib/apk/db/installed'), 100000, 100000) + +# /lib/apk/db/scripts.tar +tmp_tar_path = tempfile.mkstemp()[1] +files_in_tar = [] +with tarfile.open(tmp_tar_path, 'w:') as tmp_tar: + for layer in layers: + tar_path = os.path.join(layer, 'lib/apk/db/scripts.tar') + if os.path.exists(tar_path): + with tarfile.open(tar_path, 'r:') as tar: + for member in tar.getmembers(): + if member.name not in files_in_tar: + buffer = tar.extractfile(member) + tmp_tar.addfile(member, buffer) + files_in_tar.append(member.name) +if files_in_tar: + shutil.move(tmp_tar_path, os.path.join(layers[-1], 'lib/apk/db/scripts.tar')) + os.chown(os.path.join(layers[-1], 'lib/apk/db/scripts.tar'), 100000, 100000) +else: + os.unlink(tmp_tar_path) + +# /lib/apk/db/triggers +triggers = [] +for layer in layers: + try: + with open(os.path.join(layer, 'lib/apk/db/triggers'), 'r') as f: + for line in f: + if line not in triggers: + triggers.append(line) + except: + continue +with open(os.path.join(layers[-1], 'lib/apk/db/triggers'), 'w') as f: + f.writelines(triggers) +os.chown(os.path.join(layers[-1], 'lib/apk/db/triggers'), 100000, 100000)