454 lines
17 KiB
Python
454 lines
17 KiB
Python
# -*- coding: utf-8 -*-
|
|
|
|
"""
|
|
脚本作用:
|
|
A)指定分区img转化格式
|
|
B)制作pac
|
|
C)拷贝营运商信息、img、bin、xml等到out指定目录,不压缩
|
|
|
|
调用方法
|
|
python makepac.py
|
|
"""
|
|
|
|
|
|
import os
|
|
import sys
|
|
try:
|
|
# python2
|
|
reload(sys)
|
|
sys.setdefaultencoding('utf-8')
|
|
except:
|
|
# Python3
|
|
import importlib
|
|
importlib.reload(sys)
|
|
|
|
import filecmp
|
|
import shutil
|
|
import time
|
|
import subprocess
|
|
from csv import reader
|
|
#import ConfigParser
|
|
from symbols import BMConfigDir
|
|
from bt_version import BT_VERSION
|
|
import optparse
|
|
try:
|
|
# Python3
|
|
from configparser import ConfigParser
|
|
except ImportError:
|
|
# Python2
|
|
from ConfigParser import ConfigParser
|
|
|
|
CONFIG_FILE = "pac.ini"
|
|
PAC_TAR = "archive_images"
|
|
partition = "partition"
|
|
SIMG2IMG = "out/host/linux-x86/bin/simg2img"
|
|
RENAME_IMG_LIST = []
|
|
CARRIER_LIST = []
|
|
PAC_LIST = []
|
|
NOT_PAC_LIST = []
|
|
SCRIPT_PATH = os.path.dirname(os.path.realpath(__file__))
|
|
|
|
|
|
def main(board_path):
|
|
if not board_path:
|
|
board_path = 'out/target/product'
|
|
BOARD_PATHS = os.environ.get("OUT")
|
|
if BOARD_PATHS:
|
|
BOARD_target = BOARD_PATHS.split("/")[-1]
|
|
board_path = board_path + "/" + BOARD_target
|
|
cmd = 'find {} -maxdepth 1 -name "*.xml"'.format(board_path)
|
|
output = exec_cmd(cmd)
|
|
print(output)
|
|
target_board_file = output.strip().split('\n')
|
|
target_board_path,target_board = os.path.split(target_board_file[0])
|
|
if not target_board_path:
|
|
target_board_path = board_path
|
|
print("[TARGET_BOARD]:"+str(target_board_path))
|
|
|
|
restore_product(target_board_path)
|
|
##判断是否编译过ota##########
|
|
is_check_ota = False
|
|
native_folder = os.path.join(target_board_path, "native_backup")
|
|
if os.path.exists(os.path.join(target_board_path,"make_ota_flag")):
|
|
if os.path.exists(native_folder):
|
|
print("copy backup img from native_backup")
|
|
is_check_ota = True
|
|
for img in os.listdir(native_folder):
|
|
img_path = os.path.join(native_folder, img)
|
|
if os.path.isfile(img_path) and os.path.splitext(img_path)[1] == ".img":
|
|
if os.path.exists(os.path.join(target_board_path, img)):
|
|
os.remove(os.path.join(target_board_path, img))
|
|
shutil.copy(img_path, target_board_path)
|
|
else:
|
|
print("not find native_backup folder")
|
|
##判断cp_sign是否存在,如果cp_sign 目录不存在也会打包###
|
|
cp_sign = os.path.join(target_board_path, "cp_sign")
|
|
if os.path.exists(cp_sign):
|
|
carrier_product_list = []
|
|
native_product_list = []
|
|
product_list = os.listdir(cp_sign)
|
|
for product in product_list:
|
|
product_path = os.path.join(cp_sign, product)
|
|
if os.path.isfile(product_path):
|
|
continue
|
|
pac_ini_path = os.path.join(product_path, "pac.ini")
|
|
carrier = read_carrier(pac_ini_path)
|
|
if carrier.strip():
|
|
carrier_product_list.append(product)
|
|
else:
|
|
native_product_list.append(product)
|
|
|
|
print("=============== perl mkpac start =======================")
|
|
|
|
|
|
for product in native_product_list:
|
|
product_path = os.path.join(cp_sign, product)
|
|
if os.path.isdir(product_path):
|
|
print("*******[ap product:"+product+"]*************")
|
|
backup_product(product_path)
|
|
get_ap_product(product_path,target_board_path,is_check_ota)
|
|
get_pac(product_path, target_board_path)
|
|
|
|
|
|
for product in carrier_product_list:
|
|
product_path = os.path.join(cp_sign, product)
|
|
if os.path.isdir(product_path):
|
|
print("*******[ap product:"+product+"]*************")
|
|
get_ap_product(product_path,target_board_path,is_check_ota)
|
|
get_pac(product_path, target_board_path)
|
|
|
|
print("pac list:[")
|
|
if len(PAC_LIST):
|
|
for pac in PAC_LIST:
|
|
print(pac+" [PASS]")
|
|
if len(NOT_PAC_LIST):
|
|
for pac_fail in NOT_PAC_LIST:
|
|
print(pac_fail+" [FAIL]")
|
|
print("]")
|
|
print("=============== perl mkpac end =========================")
|
|
else:
|
|
print("not find cp_sign")
|
|
###########copy tar#############
|
|
restore_product(target_board_path)
|
|
|
|
print("tart copy *img *bin etc")
|
|
copy_tar(target_board_path)
|
|
###########rename spase image#######
|
|
print("unsparse list:")
|
|
print(RENAME_IMG_LIST)
|
|
if len(RENAME_IMG_LIST):
|
|
for rename_img in RENAME_IMG_LIST:
|
|
print("rename_img:"+rename_img)
|
|
if not os.path.exists(rename_img):
|
|
print("not find "+rename_img)
|
|
continue
|
|
image_path,image_name = os.path.split(rename_img)
|
|
new_img_name = image_name[5:]
|
|
new_img_path = os.path.join(image_path, new_img_name)
|
|
if os.path.exists(new_img_path):
|
|
os.remove(new_img_path)
|
|
os.rename(rename_img, new_img_path)
|
|
else:
|
|
print("not unsparse image")
|
|
|
|
restore_product(target_board_path)
|
|
|
|
def backup_product(product_path):
|
|
pac_ini_path = os.path.join(product_path, "pac.ini")
|
|
product_value = get_carrier_partition(pac_ini_path)
|
|
if not product_value.strip():
|
|
print("not find product partition")
|
|
return
|
|
product_img_name = product_value.split('/')[-1]
|
|
product_img_path_tmp ='/'.join(product_value.split('/')[:-1])
|
|
filename_new = "MAKEPAC-" + product_img_name
|
|
if not os.path.exists(os.path.join(product_img_path_tmp, filename_new)):
|
|
print("=====backup_product=====:"+str(product_path))
|
|
shutil.copy(product_value, os.path.join(product_img_path_tmp, filename_new))
|
|
|
|
def restore_product(target_board_path):
|
|
print("rename TEMP- and MAKEPAC-")
|
|
file_list = os.listdir(target_board_path)
|
|
for file in file_list:
|
|
file_path = os.path.join(target_board_path, file)
|
|
if os.path.isfile(file_path):
|
|
if file.startswith("MAKEPAC-"):
|
|
print("rename MAKEPAC- file:"+file)
|
|
new_file_name = file[8:]
|
|
if os.path.exists(os.path.join(target_board_path, new_file_name)):
|
|
os.remove(os.path.join(target_board_path, new_file_name))
|
|
os.rename(os.path.join(target_board_path, file), os.path.join(target_board_path, new_file_name))
|
|
elif file.startswith("TEMP-"):
|
|
print("rename TEMP- file:"+file)
|
|
new_file_name = file[5:]
|
|
if os.path.exists(os.path.join(target_board_path, new_file_name)):
|
|
os.remove(os.path.join(target_board_path, new_file_name))
|
|
os.rename(os.path.join(target_board_path, file), os.path.join(target_board_path, new_file_name))
|
|
|
|
def copy_tar(target_board_path):
|
|
if os.path.exists(os.path.join(target_board_path, "repac")):
|
|
print("repac,no need create archive_images")
|
|
return
|
|
imges_folder = os.path.join(target_board_path, PAC_TAR)
|
|
if os.path.exists(imges_folder):
|
|
shutil.rmtree(imges_folder,True)
|
|
os.mkdir(imges_folder)
|
|
current_pwd = os.getcwd()
|
|
os.chdir(target_board_path)
|
|
tar_cmd = 'find . -maxdepth 1 -name "*.img" -o -name "*.bin" -o -name "*.xml" -o -name "installed-files.txt" -o -name "PRODUCT_SECURE_BOOT_SPRD" | awk -F "/" \'{print$2}\''
|
|
output = os.popen(tar_cmd)
|
|
image_list = output.read().strip().replace('\n',',').split(',')
|
|
os.chdir(current_pwd)
|
|
|
|
if len(image_list):
|
|
for img in image_list:
|
|
if not img.startswith("TEMP-"):
|
|
img_old_path = os.path.join(target_board_path, img)
|
|
shutil.copy(img_old_path, imges_folder)
|
|
|
|
native_folder = os.path.join(target_board_path, "native_backup")
|
|
if os.path.exists(native_folder):
|
|
for img in os.listdir(native_folder):
|
|
img_path = os.path.join(native_folder, img)
|
|
if os.path.isfile(img_path) and os.path.splitext(img_path)[1] == ".img":
|
|
if os.path.exists(os.path.join(imges_folder, img)):
|
|
os.remove(os.path.join(imges_folder, img))
|
|
shutil.copy(img_path, imges_folder)
|
|
|
|
print("carrier list:")
|
|
global CARRIER_LIST
|
|
CARRIER_LIST = list(set(CARRIER_LIST))
|
|
print(CARRIER_LIST)
|
|
if len(CARRIER_LIST):
|
|
for carrier in CARRIER_LIST:
|
|
carrier_folder = os.path.join(imges_folder, carrier)
|
|
if os.path.exists(carrier_folder):
|
|
shutil.rmtree(carrier_folder,True)
|
|
os.mkdir(carrier_folder)
|
|
|
|
carrier_path = os.path.join(target_board_path, carrier)
|
|
carrier_folder_list = os.listdir(carrier_path)
|
|
for carrier_file in carrier_folder_list:
|
|
carrier_file_path = os.path.join(carrier_path, carrier_file)
|
|
if os.path.isfile(carrier_file_path) and not carrier_file.startswith('TEMP-'):
|
|
shutil.copy(carrier_file_path, carrier_folder)
|
|
|
|
#删除modem bin文件
|
|
if os.path.exists(os.path.join(target_board_path, "make_ota_flag")):
|
|
f = open(os.path.join(target_board_path, "make_ota_flag"), 'r')
|
|
bin_list = f.read().strip()
|
|
f.close()
|
|
bin_list = bin_list.split(',')
|
|
print(bin_list)
|
|
for bin in bin_list:
|
|
if os.path.exists(os.path.join(imges_folder, bin)):
|
|
os.remove(os.path.join(imges_folder, bin))
|
|
|
|
def get_pac(product_path, target_board_path):
|
|
conf = BMConfigParser()
|
|
conf.read(os.path.join(product_path, "pac.ini"))
|
|
pac_name = conf.get("Attr", "PAC_NAME")
|
|
if pac_name.strip():
|
|
pac_path = os.path.join(product_path, pac_name)
|
|
if os.path.exists(pac_path):
|
|
PAC_LIST.append(pac_name)
|
|
make_bt_version(product_path, target_board_path)
|
|
else:
|
|
NOT_PAC_LIST.append(pac_name)
|
|
|
|
def get_ap_product(product_path, target_board_path, is_check_ota):
|
|
############查询carrier###########
|
|
carrier = ''
|
|
carrier_flag = os.path.join(product_path, "pac.ini")
|
|
if os.path.exists(carrier_flag):
|
|
carrier = read_carrier(carrier_flag)
|
|
if carrier.strip():
|
|
CARRIER_LIST.append(carrier)
|
|
#######转换格式########
|
|
pac_ini_path = os.path.join(product_path, "pac.ini")
|
|
sparse_list = parser_pac_ini(pac_ini_path)
|
|
if len(sparse_list):
|
|
for img in sparse_list:
|
|
img = '/'.join(img.split('/')[1:])
|
|
image_path,image_name = os.path.split(img)
|
|
##判断之前是否已转换过
|
|
check_sparse = os.path.join(image_path, "TEMP-"+image_name)
|
|
if os.path.exists(check_sparse):
|
|
print("has unsparse %s"%image_name)
|
|
else:
|
|
sparse_check(img, image_path, "unsparse-"+image_name)
|
|
else:
|
|
print("not transfer sparse img ")
|
|
#########打pac包##################
|
|
mkpac_pl = os.path.join(SCRIPT_PATH, "mkpac.pl")
|
|
current_pwd = os.getcwd()
|
|
os.chdir(product_path)
|
|
print("current path:"+os.getcwd())
|
|
cmd = "perl %s"%(mkpac_pl)
|
|
exec_cmd(cmd)
|
|
os.chdir(current_pwd)
|
|
|
|
def read_carrier(carrier_flag):
|
|
carrier_value = ''
|
|
conf = BMConfigParser()
|
|
conf.read(carrier_flag)
|
|
options_list = conf.options("Attr")
|
|
if "carrier" not in options_list:
|
|
print("not configured carrier")
|
|
return carrier_value
|
|
carrier_value = conf.get("Attr", "carrier")
|
|
return carrier_value
|
|
|
|
def get_carrier_partition(carrier_flag):
|
|
carrier_partition = ''
|
|
conf = BMConfigParser()
|
|
conf.read(carrier_flag)
|
|
options_list = conf.options("partition")
|
|
if "carrier_partition" not in options_list:
|
|
print("not configured carrier_partition")
|
|
return carrier_partition
|
|
carrier_product = conf.get("partition", "carrier_partition")
|
|
|
|
pac_list = conf.options("pac_list")
|
|
if carrier_product not in pac_list:
|
|
print("not carrier_partition in pac_list")
|
|
return carrier_partition
|
|
product_value = conf.get("pac_list", carrier_product)
|
|
|
|
if not product_value.strip():
|
|
print("find product_value in empty")
|
|
return carrier_partition
|
|
|
|
product_value = '/'.join(product_value.split('/')[1:])
|
|
|
|
print("get_carrier_partition--product_value:" + str(product_value))
|
|
|
|
return product_value
|
|
|
|
|
|
def sparse_check(installed_systeimage, product_out, upsparse_image):
|
|
print("installed_systeimage:"+str(installed_systeimage)) #需要转换的image
|
|
print("product_out:"+str(product_out)) #image路径
|
|
print("SIMG2IMG:"+str(SIMG2IMG))#转换工具·
|
|
#upsparse_image 转换后的img 名称
|
|
system_header = os.path.join(product_out, "system_header.img")
|
|
sparse_magic = os.path.join(product_out, "sparse_magic.img")
|
|
if os.path.exists(system_header):
|
|
cmd = "dd if=%s of=%s bs=1 skip=0 count=4"%(installed_systeimage, system_header)
|
|
exec_cmd(cmd)
|
|
with open(sparse_magic, 'w') as out_in:
|
|
out_in.write("\x3a\xff\x26\xed")
|
|
|
|
result = filecmp.cmp(system_header, sparse_magic, False)
|
|
print("cmp result:"+str(result))
|
|
if result:
|
|
print("[%s]transfer sparse img to unsparse img"%installed_systeimage)
|
|
sparse_cmd = "%s %s %s"%(SIMG2IMG, installed_systeimage, os.path.join(product_out, upsparse_image))
|
|
exec_cmd(sparse_cmd)
|
|
else:
|
|
print("[%s]not transfer sparse img"%installed_systeimage)
|
|
os.remove(sparse_magic)
|
|
os.remove(system_header)
|
|
|
|
#####对已转换格式的img重命名##########
|
|
upsparse_image_path = os.path.join(product_out, upsparse_image)
|
|
if os.path.exists(upsparse_image_path):
|
|
image_path,image_name = os.path.split(installed_systeimage)
|
|
new_img_name = os.path.join(image_path, "TEMP-"+image_name)
|
|
os.rename(installed_systeimage, new_img_name)
|
|
RENAME_IMG_LIST.append(new_img_name)
|
|
os.rename(upsparse_image_path, installed_systeimage)
|
|
|
|
|
|
def parser_pac_ini(pac_ini_path):
|
|
#解析ini数据
|
|
print("pac_ini_path:"+str(pac_ini_path))
|
|
params = []
|
|
if not os.path.exists(pac_ini_path):
|
|
print("not find: %s"%pac_ini_path)
|
|
return params
|
|
|
|
conf = BMConfigParser()
|
|
conf.read(pac_ini_path)
|
|
options_list = conf.options("partition")
|
|
if "sparse" not in options_list:
|
|
print("%s not configured sparse"%pac_ini_path)
|
|
return params
|
|
|
|
sparse_config = conf.get("partition", "sparse")
|
|
sparse_list = []
|
|
if sparse_config.strip():
|
|
if ',' in sparse_config:
|
|
sparse_list.extend(sparse_config.strip().split(','))
|
|
else:
|
|
sparse_list.append(sparse_config.strip())
|
|
else:
|
|
print("%s not configured sparse value"%pac_ini_path)
|
|
return params
|
|
|
|
image_list = conf.options("pac_list")
|
|
for sp in sparse_list:
|
|
if sp not in image_list:
|
|
continue
|
|
sparse_path = conf.get("pac_list", sp).strip()
|
|
params.append(sparse_path)
|
|
|
|
return params
|
|
|
|
def exec_cmd(cmd, use_shell=False):
|
|
print("exec command: " + cmd)
|
|
cmd_list = split(cmd)
|
|
proc = subprocess.Popen(cmd_list, stdout=subprocess.PIPE, stderr=subprocess.STDOUT, shell=use_shell)
|
|
|
|
(output, error) = proc.communicate()
|
|
print("command output: " + output.decode())
|
|
# exit_code = proc.wait()
|
|
return output.decode()
|
|
|
|
def split(s):
|
|
for row in reader([s], delimiter=" "):
|
|
return row
|
|
|
|
def make_bt_version(product_type, target_board_path):
|
|
time_tup = time.localtime(time.time())
|
|
format_time = '%Y-%m-%d-%a:%H:%M'
|
|
cur_time = time.strftime(format_time, time_tup)
|
|
bt = BT_VERSION(product_type, cur_time, target_board_path)
|
|
bt.out_version(target_board_path)
|
|
|
|
class BMConfigParser(ConfigParser):
|
|
def __init__(self, defaults=None):
|
|
ConfigParser.__init__(self, defaults=defaults)
|
|
|
|
def optionxform(self, option_str):
|
|
return option_str
|
|
def help():
|
|
init_optparse = optparse.OptionParser(
|
|
usage="usage: %prog [options] args", description="show help"
|
|
)
|
|
init_optparse.add_option(
|
|
'-o', '--out', help='output path', dest='output', type="string")
|
|
init_optparse.add_option(
|
|
'-p', '--tool-path', help='tool path', type="string")
|
|
|
|
(options, args) = init_optparse.parse_args()
|
|
#if not options.output:
|
|
# print init_optparse.error('Insufficient number of arguments')
|
|
# sys.exit(1)
|
|
return options
|
|
|
|
if __name__ == "__main__":
|
|
options = help()
|
|
print("=============== makepac.py start =======================")
|
|
config = BMConfigDir(SCRIPT_PATH)
|
|
dir = config.get_dir()
|
|
print("dir:" + dir)
|
|
print("SCRIPT_PATH path:"+SCRIPT_PATH)
|
|
code_path = SCRIPT_PATH.split(dir)[0]
|
|
os.chdir(code_path)
|
|
print("pwd:" + os.getcwd())
|
|
if options.tool_path:
|
|
SIMG2IMG = os.path.join(options.tool_path, 'simg2img')
|
|
main(options.output)
|
|
print("=============== makepac.py end =========================")
|