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