140681896Sopenharmony_ci#!/usr/bin/env python 240681896Sopenharmony_ci# -*- coding: utf-8 -*- 340681896Sopenharmony_ci# Copyright (c) 2021 Huawei Device Co., Ltd. 440681896Sopenharmony_ci# Licensed under the Apache License, Version 2.0 (the "License"); 540681896Sopenharmony_ci# you may not use this file except in compliance with the License. 640681896Sopenharmony_ci# You may obtain a copy of the License at 740681896Sopenharmony_ci# 840681896Sopenharmony_ci# http://www.apache.org/licenses/LICENSE-2.0 940681896Sopenharmony_ci# 1040681896Sopenharmony_ci# Unless required by applicable law or agreed to in writing, software 1140681896Sopenharmony_ci# distributed under the License is distributed on an "AS IS" BASIS, 1240681896Sopenharmony_ci# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 1340681896Sopenharmony_ci# See the License for the specific language governing permissions and 1440681896Sopenharmony_ci# limitations under the License. 1540681896Sopenharmony_ciimport ast 1640681896Sopenharmony_ciimport os 1740681896Sopenharmony_ciimport shutil 1840681896Sopenharmony_ciimport zipfile 1940681896Sopenharmony_ci 2040681896Sopenharmony_cifrom test.fake_data import RSA_PRIVATE_KEY_DATA 2140681896Sopenharmony_ci 2240681896Sopenharmony_ciUPDATER_BINARY_DATA = b"updater binary data" 2340681896Sopenharmony_ciBOARD_LIST_DATA = b"""HI3516 2440681896Sopenharmony_ciHI3518 2540681896Sopenharmony_ciHI3559""" 2640681896Sopenharmony_ciVERSION_MBN_DATA = b"""Hi3516DV300-eng 10 QP1A.190711.020 2740681896Sopenharmony_ciHi3516DV300-eng 10 QP1A.190711.021""" 2840681896Sopenharmony_ci 2940681896Sopenharmony_ciUPDATER_SPECIFIED_CONFIG_XML_DATA = """<?xml version="1.0"?> 3040681896Sopenharmony_ci<package> 3140681896Sopenharmony_ci <head name="Component header information"> 3240681896Sopenharmony_ci <info fileVersion="01" prdID="123456" 3340681896Sopenharmony_ci softVersion="Hi3516DV300-eng 10 QP1A.190711.0VERSION_MARK" 3440681896Sopenharmony_ci date="2021-01-23" time="12:30">head info</info> 3540681896Sopenharmony_ci </head> 3640681896Sopenharmony_ci <group name = "Component information"> 3740681896Sopenharmony_ci SYSTEM_MARK 3840681896Sopenharmony_ci COMPONENT_MARK 3940681896Sopenharmony_ci </group> 4040681896Sopenharmony_ci</package>""" 4140681896Sopenharmony_ciUPDATER_PARTITIONS_XML_DATA = b"""<?xml version="1.0" encoding="GB2312" ?> 4240681896Sopenharmony_ci<Partition_Info> 4340681896Sopenharmony_ci<Part PartitionName="boot" FlashType="emmc" FileSystem="none" 4440681896Sopenharmony_ci Start="0" Length="1M"/> 4540681896Sopenharmony_ci<Part PartitionName="kernel" FlashType="emmc" FileSystem="none" 4640681896Sopenharmony_ci Start="1M" Length="15M"/> 4740681896Sopenharmony_ci<Part PartitionName="updater" FlashType="emmc" FileSystem="ext3/4" 4840681896Sopenharmony_ci Start="16M" Length="20M"/> 4940681896Sopenharmony_ci<Part PartitionName="misc" FlashType="emmc" FileSystem="none" 5040681896Sopenharmony_ci Start="36M" Length="1M"/> 5140681896Sopenharmony_ci<Part PartitionName="system" FlashType="emmc" FileSystem="ext3/4" 5240681896Sopenharmony_ci Start="37M" Length="3300M"/> 5340681896Sopenharmony_ci<Part PartitionName="vendor" FlashType="emmc" FileSystem="ext3/4" 5440681896Sopenharmony_ci Start="3337M" Length="263M"/> 5540681896Sopenharmony_ci<Part PartitionName="userdata" FlashType="emmc" FileSystem="ext3/4" 5640681896Sopenharmony_ci Start="3600M" Length="1464M"/> 5740681896Sopenharmony_ci</Partition_Info>""" 5840681896Sopenharmony_ci 5940681896Sopenharmony_ciSYSTEM_COMPONENT_STR = """<component compAddr="system" compId="12" 6040681896Sopenharmony_ci resType="05" compType="0" compVer="0o00">./system.img</component>""" 6140681896Sopenharmony_ciCOMPONENT_STR_INC = """<component compAddr="vendor" compId="13" 6240681896Sopenharmony_ci resType="05" compType="1" compVer="0o00">./vendor.img</component>""" 6340681896Sopenharmony_ciCOMPONENT_STR_FULL = """<component compAddr="vendor" compId="13" 6440681896Sopenharmony_ci resType="05" compType="0" compVer="0o00">./vendor.img</component>""" 6540681896Sopenharmony_ciCOMPONENT_STR_USERDATA = """<component compAddr="userdata" compId="14" 6640681896Sopenharmony_ci resType="05" compType="0" compVer="0o00">./userdata.img</component>""" 6740681896Sopenharmony_ciSOURCE_VERSION_STR = "20" 6840681896Sopenharmony_ciTARGET_VERSION_STR = "21" 6940681896Sopenharmony_ci 7040681896Sopenharmony_ci 7140681896Sopenharmony_cidef create_input_package( 7240681896Sopenharmony_ci package_name, package_type="target", is_su=False, 7340681896Sopenharmony_ci is_updater_partitions=False, has_userdata=False, 7440681896Sopenharmony_ci is_inc_full_none=False, is_miss_image=False, 7540681896Sopenharmony_ci is_miss_version_list=False, is_miss_updater_binary=False): 7640681896Sopenharmony_ci """ 7740681896Sopenharmony_ci Create input package. 7840681896Sopenharmony_ci :param package_name: package name 7940681896Sopenharmony_ci :param package_type: package type, source or target 8040681896Sopenharmony_ci :param is_su: Is it an updater upgrade package 8140681896Sopenharmony_ci :param is_updater_partitions: Is it an updater partitions upgrade package 8240681896Sopenharmony_ci :param has_userdata: Configuring UserData in XML 8340681896Sopenharmony_ci :param is_inc_full_none: Both full and incremental list lengths are zero 8440681896Sopenharmony_ci :param is_miss_image: Is image missing 8540681896Sopenharmony_ci :param is_miss_version_list: Is VERSION.list missing 8640681896Sopenharmony_ci :param is_miss_updater_binary: Is updater_binary missing 8740681896Sopenharmony_ci :return: 8840681896Sopenharmony_ci """ 8940681896Sopenharmony_ci # Create a folder for the input package. 9040681896Sopenharmony_ci package_name_path = "./%s" % package_name 9140681896Sopenharmony_ci if not os.path.exists(package_name_path): 9240681896Sopenharmony_ci os.mkdir(package_name_path) 9340681896Sopenharmony_ci 9440681896Sopenharmony_ci if not is_miss_image: 9540681896Sopenharmony_ci create_file(os.path.join(package_name_path, "system.img"), get_target_vendor_data()) 9640681896Sopenharmony_ci 9740681896Sopenharmony_ci # Judge the type of input package and generate the corresponding vendor.img 9840681896Sopenharmony_ci if package_type == "target": 9940681896Sopenharmony_ci vendor_content = get_target_vendor_data() 10040681896Sopenharmony_ci elif package_type == "source": 10140681896Sopenharmony_ci vendor_content = get_source_vendor_data() 10240681896Sopenharmony_ci else: 10340681896Sopenharmony_ci print("Unknown package type!") 10440681896Sopenharmony_ci raise RuntimeError 10540681896Sopenharmony_ci if not is_miss_image: 10640681896Sopenharmony_ci create_file(os.path.join(package_name_path, "vendor.img"), vendor_content) 10740681896Sopenharmony_ci if not is_miss_updater_binary: 10840681896Sopenharmony_ci create_file(os.path.join(package_name_path, "updater_binary"), UPDATER_BINARY_DATA) 10940681896Sopenharmony_ci # updater upgrade package 11040681896Sopenharmony_ci if is_su: 11140681896Sopenharmony_ci create_file(os.path.join(package_name_path, "uImage"), get_target_vendor_data()) 11240681896Sopenharmony_ci create_file(os.path.join(package_name_path, "updater.img"), get_target_vendor_data()) 11340681896Sopenharmony_ci create_file(os.path.join(package_name_path, "updater_b.img"), get_target_vendor_data()) 11440681896Sopenharmony_ci create_file(os.path.join(package_name_path, "updater_uImage"), get_target_vendor_data()) 11540681896Sopenharmony_ci # Create updater_config dir. 11640681896Sopenharmony_ci updater_config_path = "./%s/updater_config" % package_name 11740681896Sopenharmony_ci if not os.path.exists(updater_config_path): 11840681896Sopenharmony_ci os.mkdir(updater_config_path) 11940681896Sopenharmony_ci create_file(os.path.join(updater_config_path, "BOARD.list"), BOARD_LIST_DATA) 12040681896Sopenharmony_ci if not is_miss_version_list: 12140681896Sopenharmony_ci create_file(os.path.join(updater_config_path, "VERSION.mbn"), VERSION_MBN_DATA) 12240681896Sopenharmony_ci # Judge the type of input package and 12340681896Sopenharmony_ci xml_content = \ 12440681896Sopenharmony_ci create_updater_specified_config_file(has_userdata, is_updater_partitions, package_type) 12540681896Sopenharmony_ci 12640681896Sopenharmony_ci if is_inc_full_none: 12740681896Sopenharmony_ci xml_content = xml_content.replace("SYSTEM_MARK", "") 12840681896Sopenharmony_ci xml_content = xml_content.replace("COMPONENT_MARK", "") 12940681896Sopenharmony_ci else: 13040681896Sopenharmony_ci xml_content = xml_content.replace("SYSTEM_MARK", SYSTEM_COMPONENT_STR) 13140681896Sopenharmony_ci xml_content = xml_content.replace("COMPONENT_MARK", COMPONENT_STR_FULL) 13240681896Sopenharmony_ci 13340681896Sopenharmony_ci create_file(os.path.join(updater_config_path, "updater_specified_config.xml"), xml_content) 13440681896Sopenharmony_ci # Create partition_file.xml. 13540681896Sopenharmony_ci if is_updater_partitions: 13640681896Sopenharmony_ci create_file("./partition_file.xml", UPDATER_PARTITIONS_XML_DATA) 13740681896Sopenharmony_ci # Create rsa_private_key2048.pem. 13840681896Sopenharmony_ci create_file("./rsa_private_key2048.pem", RSA_PRIVATE_KEY_DATA) 13940681896Sopenharmony_ci # Create zip package. 14040681896Sopenharmony_ci with zipfile.ZipFile('./%s.zip' % package_name, 'w', zipfile.ZIP_DEFLATED) as package_zip: 14140681896Sopenharmony_ci package_zip.write(package_name_path) 14240681896Sopenharmony_ci for home, dirs, files in os.walk(package_name_path): 14340681896Sopenharmony_ci for each_file_name in files: 14440681896Sopenharmony_ci package_zip.write(os.path.join(home, each_file_name)) 14540681896Sopenharmony_ci for each_dir_name in dirs: 14640681896Sopenharmony_ci package_zip.write(os.path.join(home, each_dir_name)) 14740681896Sopenharmony_ci 14840681896Sopenharmony_ci 14940681896Sopenharmony_cidef create_updater_specified_config_file( 15040681896Sopenharmony_ci has_userdata, is_updater_partitions, package_type): 15140681896Sopenharmony_ci """ 15240681896Sopenharmony_ci generate the corresponding updater_specified_config.xml 15340681896Sopenharmony_ci :param has_userdata: has userdata 15440681896Sopenharmony_ci :param is_updater_partitions: is updater partitions 15540681896Sopenharmony_ci :param package_type: package type 15640681896Sopenharmony_ci :return: 15740681896Sopenharmony_ci """ 15840681896Sopenharmony_ci if package_type == "target": 15940681896Sopenharmony_ci xml_content = UPDATER_SPECIFIED_CONFIG_XML_DATA.replace( 16040681896Sopenharmony_ci "VERSION_MARK", TARGET_VERSION_STR) 16140681896Sopenharmony_ci xml_content = xml_content.replace( 16240681896Sopenharmony_ci "COMPONENT_MARK", COMPONENT_STR_INC) 16340681896Sopenharmony_ci elif package_type == "source": 16440681896Sopenharmony_ci xml_content = UPDATER_SPECIFIED_CONFIG_XML_DATA.replace( 16540681896Sopenharmony_ci "VERSION_MARK", SOURCE_VERSION_STR) 16640681896Sopenharmony_ci if is_updater_partitions: 16740681896Sopenharmony_ci xml_content = xml_content.replace( 16840681896Sopenharmony_ci "COMPONENT_MARK", COMPONENT_STR_FULL) 16940681896Sopenharmony_ci elif has_userdata: 17040681896Sopenharmony_ci xml_content = xml_content.replace( 17140681896Sopenharmony_ci "COMPONENT_MARK", COMPONENT_STR_USERDATA) 17240681896Sopenharmony_ci else: 17340681896Sopenharmony_ci print("Unknown package type!") 17440681896Sopenharmony_ci raise RuntimeError 17540681896Sopenharmony_ci return xml_content 17640681896Sopenharmony_ci 17740681896Sopenharmony_ci 17840681896Sopenharmony_cidef create_file(file_path, file_data): 17940681896Sopenharmony_ci """ 18040681896Sopenharmony_ci Create file 18140681896Sopenharmony_ci :param file_path: file path 18240681896Sopenharmony_ci :param file_data: file data 18340681896Sopenharmony_ci :return: 18440681896Sopenharmony_ci """ 18540681896Sopenharmony_ci with open(file_path, "wb") as w_f: 18640681896Sopenharmony_ci w_f.write(file_data) 18740681896Sopenharmony_ci 18840681896Sopenharmony_ci 18940681896Sopenharmony_cidef clear_package(package_name): 19040681896Sopenharmony_ci """ 19140681896Sopenharmony_ci Clean up the constructed input package and files 19240681896Sopenharmony_ci :param package_name: constructed input package name 19340681896Sopenharmony_ci :return: 19440681896Sopenharmony_ci """ 19540681896Sopenharmony_ci if os.path.exists("./%s" % package_name): 19640681896Sopenharmony_ci shutil.rmtree("./%s" % package_name) 19740681896Sopenharmony_ci if os.path.exists("./%s.zip" % package_name): 19840681896Sopenharmony_ci os.remove("./%s.zip" % package_name) 19940681896Sopenharmony_ci if os.path.exists("./partition_file.xml"): 20040681896Sopenharmony_ci os.remove("./partition_file.xml") 20140681896Sopenharmony_ci if os.path.exists("./rsa_private_key2048.pem"): 20240681896Sopenharmony_ci os.remove("./rsa_private_key2048.pem") 20340681896Sopenharmony_ci 20440681896Sopenharmony_ci 20540681896Sopenharmony_cidef get_source_vendor_data(): 20640681896Sopenharmony_ci """ 20740681896Sopenharmony_ci Get source vendor image file data 20840681896Sopenharmony_ci :return: 20940681896Sopenharmony_ci """ 21040681896Sopenharmony_ci with open(r"./source_vendor_data", "r") as r_f: 21140681896Sopenharmony_ci content = r_f.read() 21240681896Sopenharmony_ci return ast.literal_eval(content) 21340681896Sopenharmony_ci 21440681896Sopenharmony_ci 21540681896Sopenharmony_cidef get_target_vendor_data(): 21640681896Sopenharmony_ci """ 21740681896Sopenharmony_ci Get target vendor image file data 21840681896Sopenharmony_ci :return: 21940681896Sopenharmony_ci """ 22040681896Sopenharmony_ci with open(r"./target_vendor_data", "r") as r_f: 22140681896Sopenharmony_ci content = r_f.read() 22240681896Sopenharmony_ci return ast.literal_eval(content) 223