95 lines
		
	
	
		
			3.2 KiB
		
	
	
	
		
			Python
		
	
	
		
			Executable File
		
	
	
	
	
			
		
		
	
	
			95 lines
		
	
	
		
			3.2 KiB
		
	
	
	
		
			Python
		
	
	
		
			Executable File
		
	
	
	
	
| #!/usr/bin/python3
 | |
| # -*- coding: utf-8 -*-
 | |
| 
 | |
| import argparse
 | |
| import os
 | |
| import shutil
 | |
| import sys
 | |
| import tarfile
 | |
| import tempfile
 | |
| 
 | |
| parser = argparse.ArgumentParser(description='APK database merge script')
 | |
| parser.add_argument('layers', help='Path to LXC layers to be merged', nargs=argparse.REMAINDER)
 | |
| 
 | |
| if len(sys.argv) < 2:
 | |
|     parser.print_usage()
 | |
|     sys.exit(1)
 | |
| args = parser.parse_args()
 | |
| layers = args.layers[::-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)
 |