#!/usr/bin/env python
# -*- coding: utf-8 -*-
# Copyright (c) 2021 Huawei Device Co., Ltd.
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
# http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.
import ast
import os
import shutil
import zipfile
from test.fake_data import RSA_PRIVATE_KEY_DATA
UPDATER_BINARY_DATA = b"updater binary data"
BOARD_LIST_DATA = b"""HI3516
HI3518
HI3559"""
VERSION_MBN_DATA = b"""Hi3516DV300-eng 10 QP1A.190711.020
Hi3516DV300-eng 10 QP1A.190711.021"""
UPDATER_SPECIFIED_CONFIG_XML_DATA = """
head info
SYSTEM_MARK
COMPONENT_MARK
"""
UPDATER_PARTITIONS_XML_DATA = b"""
"""
SYSTEM_COMPONENT_STR = """./system.img"""
COMPONENT_STR_INC = """./vendor.img"""
COMPONENT_STR_FULL = """./vendor.img"""
COMPONENT_STR_USERDATA = """./userdata.img"""
SOURCE_VERSION_STR = "20"
TARGET_VERSION_STR = "21"
def create_input_package(
package_name, package_type="target", is_su=False,
is_updater_partitions=False, has_userdata=False,
is_inc_full_none=False, is_miss_image=False,
is_miss_version_list=False, is_miss_updater_binary=False):
"""
Create input package.
:param package_name: package name
:param package_type: package type, source or target
:param is_su: Is it an updater upgrade package
:param is_updater_partitions: Is it an updater partitions upgrade package
:param has_userdata: Configuring UserData in XML
:param is_inc_full_none: Both full and incremental list lengths are zero
:param is_miss_image: Is image missing
:param is_miss_version_list: Is VERSION.list missing
:param is_miss_updater_binary: Is updater_binary missing
:return:
"""
# Create a folder for the input package.
package_name_path = "./%s" % package_name
if not os.path.exists(package_name_path):
os.mkdir(package_name_path)
if not is_miss_image:
create_file(os.path.join(package_name_path, "system.img"),
get_target_vendor_data())
# Judge the type of input package and generate the corresponding vendor.img
if package_type == "target":
vendor_content = get_target_vendor_data()
elif package_type == "source":
vendor_content = get_source_vendor_data()
else:
print("Unknown package type!")
raise RuntimeError
if not is_miss_image:
create_file(os.path.join(package_name_path, "vendor.img"),
vendor_content)
if not is_miss_updater_binary:
create_file(os.path.join(package_name_path, "updater_binary"),
UPDATER_BINARY_DATA)
# updater upgrade package
if is_su:
create_file(os.path.join(package_name_path, "uImage"),
get_target_vendor_data())
create_file(os.path.join(package_name_path, "updater.img"),
get_target_vendor_data())
create_file(os.path.join(package_name_path, "updater_b.img"),
get_target_vendor_data())
create_file(os.path.join(package_name_path, "updater_uImage"),
get_target_vendor_data())
# Create updater_config dir.
updater_config_path = "./%s/updater_config" % package_name
if not os.path.exists(updater_config_path):
os.mkdir(updater_config_path)
create_file(os.path.join(updater_config_path, "BOARD.list"),
BOARD_LIST_DATA)
if not is_miss_version_list:
create_file(os.path.join(updater_config_path, "VERSION.mbn"),
VERSION_MBN_DATA)
# Judge the type of input package and
xml_content = \
create_updater_specified_config_file(
has_userdata, is_updater_partitions, package_type)
if is_inc_full_none:
xml_content = xml_content.replace("SYSTEM_MARK", "")
xml_content = xml_content.replace(
"COMPONENT_MARK", "").encode()
else:
xml_content = xml_content.replace(
"SYSTEM_MARK", SYSTEM_COMPONENT_STR)
xml_content = xml_content.replace(
"COMPONENT_MARK", COMPONENT_STR_FULL).encode()
create_file(
os.path.join(updater_config_path, "updater_specified_config.xml"),
xml_content)
# Create partition_file.xml.
if is_updater_partitions:
create_file("./partition_file.xml", UPDATER_PARTITIONS_XML_DATA)
# Create rsa_private_key2048.pem.
create_file("./rsa_private_key2048.pem", RSA_PRIVATE_KEY_DATA)
# Create zip package.
with zipfile.ZipFile('./%s.zip' % package_name,
'w', zipfile.ZIP_DEFLATED) as package_zip:
package_zip.write(package_name_path)
for home, dirs, files in os.walk(package_name_path):
for each_file_name in files:
package_zip.write(os.path.join(home, each_file_name))
for each_dir_name in dirs:
package_zip.write(os.path.join(home, each_dir_name))
def create_updater_specified_config_file(
has_userdata, is_updater_partitions, package_type):
"""
generate the corresponding updater_specified_config.xml
:param has_userdata: has userdata
:param is_updater_partitions: is updater partitions
:param package_type: package type
:return:
"""
if package_type == "target":
xml_content = UPDATER_SPECIFIED_CONFIG_XML_DATA.replace(
"VERSION_MARK", TARGET_VERSION_STR)
xml_content = xml_content.replace(
"COMPONENT_MARK", COMPONENT_STR_INC)
elif package_type == "source":
xml_content = UPDATER_SPECIFIED_CONFIG_XML_DATA.replace(
"VERSION_MARK", SOURCE_VERSION_STR)
if is_updater_partitions:
xml_content = xml_content.replace(
"COMPONENT_MARK", COMPONENT_STR_FULL)
elif has_userdata:
xml_content = xml_content.replace(
"COMPONENT_MARK", COMPONENT_STR_USERDATA)
else:
print("Unknown package type!")
raise RuntimeError
return xml_content
def create_file(file_path, file_data):
"""
Create file
:param file_path: file path
:param file_data: file data
:return:
"""
with open(file_path, "wb") as w_f:
w_f.write(file_data)
def clear_package(package_name):
"""
Clean up the constructed input package and files
:param package_name: constructed input package name
:return:
"""
if os.path.exists("./%s" % package_name):
shutil.rmtree("./%s" % package_name)
if os.path.exists("./%s.zip" % package_name):
os.remove("./%s.zip" % package_name)
if os.path.exists("./partition_file.xml"):
os.remove("./partition_file.xml")
if os.path.exists("./rsa_private_key2048.pem"):
os.remove("./rsa_private_key2048.pem")
def get_source_vendor_data():
"""
Get source vendor image file data
:return:
"""
with open(r"./source_vendor_data", "r") as r_f:
content = r_f.read()
return ast.literal_eval(content)
def get_target_vendor_data():
"""
Get target vendor image file data
:return:
"""
with open(r"./target_vendor_data", "r") as r_f:
content = r_f.read()
return ast.literal_eval(content)