fix tool bug

Signed-off-by: ma_nan <ma_nan@hoperun.com>
This commit is contained in:
ma_nan 2021-07-29 14:02:09 +08:00
parent 8cd6d8db79
commit 68c93845d8
8 changed files with 127 additions and 49 deletions

View File

@ -43,7 +43,6 @@ import copy
import filecmp
import os
import argparse
import re
import subprocess
import xmltodict
@ -186,20 +185,18 @@ def create_entrance_args():
partition_file, signing_algorithm, hash_algorithm, private_key
def get_script_obj(script_obj=None):
def get_script_obj():
"""
获取Opera script对象
Obtain Opera script object
:return:
"""
script_obj_list = create_vendor_script_class()
if script_obj_list == [None] * len(SCRIPT_KEY_LIST) and script_obj is None:
if script_obj_list == [None] * len(SCRIPT_KEY_LIST):
prelude_script = PreludeScript()
verse_script = VerseScript()
refrain_script = RefrainScript()
ending_script = EndingScript()
else:
if script_obj_list == [None] * len(SCRIPT_KEY_LIST):
script_obj_list = script_obj
UPDATE_LOGGER.print_log(
"Get vendor extension object completed!"
"The vendor extension script will be generated.")
@ -501,11 +498,14 @@ def check_patch_file(patch_process):
diff_str = None
diff_num = 0
for line in f_t:
if 'new' in line:
num_list = line.split('\n')[0].split(',')
child_num = (int(num_list[-1]) - int(num_list[-2]))
num += child_num
if 'diff' in line:
if line.startswith('new '):
each_line_list = \
line.strip().replace("new ", "").split(",")[1:]
for idx in range(0, len(each_line_list), 2):
num += \
int(each_line_list[idx + 1]) - int(each_line_list[idx])
continue
if line.startswith('bsdiff ') or line.startswith('pkgdiff '):
diff_str = line
if diff_str:
diff_list = diff_str.split('\n')[0].split(' ')

BIN
lib/diff

Binary file not shown.

BIN
lib/libpackage.so (Stored with Git LFS)

Binary file not shown.

View File

@ -153,7 +153,7 @@ class PatchProcess:
stashed_blocks, tgt_size, total_blocks_count,
transfer_content)
else:
do_img_diff, patch_value = self.compute_diff_patch(
do_pkg_diff, patch_value = self.compute_diff_patch(
each_action, patch_dat_file_obj)
if each_action.src_block_set.is_overlaps(
@ -163,7 +163,7 @@ class PatchProcess:
if temp_stash_usage > max_stashed_blocks:
max_stashed_blocks = temp_stash_usage
self.add_diff_command(diff_offset, do_img_diff,
self.add_diff_command(diff_offset, do_pkg_diff,
each_action, patch_value, src_str,
transfer_content)
@ -224,11 +224,11 @@ class PatchProcess:
"""
Add the diff command.
"""
diff_offset, do_img_diff, each_action,\
diff_offset, do_pkg_diff, each_action,\
patch_value, src_str, transfer_content = args
self.touched_src_ranges = self.touched_src_ranges.get_union_with_other(
each_action.src_block_set)
diff_type = "imgdiff" if do_img_diff else "bsdiff"
diff_type = "pkgdiff" if do_pkg_diff else "bsdiff"
transfer_content.append("%s %d %d %s %s %s %s\n" % (
diff_type,
diff_offset, len(patch_value),
@ -254,12 +254,12 @@ class PatchProcess:
src_file_obj)
OPTIONS_MANAGER.incremental_temp_file_obj_list.append(
tgt_file_obj)
do_img_diff = True if \
do_pkg_diff = True if \
each_action.tgt_name.split(".")[-1].lower() in \
("zip", "gz", "lz4", "hap") else False
try:
patch_value, do_img_diff = self.apply_compute_patch(
src_file_obj.name, tgt_file_obj.name, do_img_diff)
patch_value, do_pkg_diff = self.apply_compute_patch(
src_file_obj.name, tgt_file_obj.name, do_pkg_diff)
except ValueError:
UPDATE_LOGGER.print_log("Patch process Failed!")
UPDATE_LOGGER.print_log("%7s %s %s (from %s %s)" % (
@ -270,7 +270,7 @@ class PatchProcess:
UPDATE_LOGGER.ERROR_LOG)
raise ValueError
patch_dat_file_obj.write(patch_value)
return do_img_diff, patch_value
return do_pkg_diff, patch_value
def add_move_command(self, *args):
"""
@ -466,12 +466,12 @@ class PatchProcess:
return total
@staticmethod
def apply_compute_patch(src_file, tgt_file, imgdiff=False):
def apply_compute_patch(src_file, tgt_file, pkgdiff=False):
"""
Add command content to the script.
:param src_file: source file name
:param tgt_file: target file name
:param imgdiff: whether to execute imgdiff judgment
:param pkgdiff: whether to execute pkgdiff judgment
:return:
"""
patch_file_obj = \
@ -479,19 +479,21 @@ class PatchProcess:
OPTIONS_MANAGER.incremental_temp_file_obj_list.append(
patch_file_obj)
cmd = [DIFF_EXE_PATH] if imgdiff else [DIFF_EXE_PATH, '-b', '1']
cmd = [DIFF_EXE_PATH] if pkgdiff else [DIFF_EXE_PATH, '-b', '1']
cmd.extend(['-s', src_file, '-d', tgt_file, '-p', patch_file_obj.name])
sub_p = subprocess.Popen(cmd, stdout=subprocess.PIPE,
stderr=subprocess.STDOUT)
output, _ = sub_p.communicate()
sub_p.wait()
patch_file_obj.seek(0)
if sub_p.returncode != 0:
raise ValueError(output)
with open(patch_file_obj.name, 'rb') as file_read:
patch_content = file_read.read()
return patch_content, imgdiff
return patch_content, pkgdiff
class PackagePatchZip:

View File

@ -361,7 +361,7 @@ def create_script(prelude_script, verse_script,
:param ending_script: ending script
:return:
"""
# 生成序幕脚本
# Generate the prelude script.
prelude_script.add_command("\n# ---- prelude ----\n")
# Get the distribution progress.
@ -402,7 +402,7 @@ def create_script(prelude_script, verse_script,
[' %s' % each for each in verse_script_content.split('\n')])
verse_script_content = verse_script_content_list[0].replace(
"ALL_WRITE_FLAG", verse_script_content)
# Generae the verse script.
# Generate the verse script.
write_script(verse_script_content, 'verse')
# Generate the refrain script.
refrain_script.add_command("\n# ---- refrain ----\n")

View File

@ -13,6 +13,7 @@
# 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 binascii
import copy
import os
import subprocess
@ -28,7 +29,9 @@ from enum import Enum
from log_exception import UPDATE_LOGGER
from script_generator import create_script
from utils import HASH_CONTENT_LEN_DICT
from utils import OPTIONS_MANAGER
from utils import REGISTER_SCRIPT_FILE_NAME
from utils import ON_SERVER
from utils import SCRIPT_KEY_LIST
from utils import EXTEND_OPTIONAL_COMPONENT_LIST
@ -57,7 +60,8 @@ class PkgHeader(Structure):
("product_update_id", c_char_p),
("software_version", c_char_p),
("date", c_char_p),
("time", c_char_p)]
("time", c_char_p),
("describe_package_id", c_char_p)]
class PkgComponent(Structure):
@ -160,16 +164,19 @@ def get_component_list(all_image_file_obj_list, component_dict):
component = copy.copy(COMPONENT_INFO_INNIT)
component[0] = key
component_list[idx].digest = (c_ubyte * 32).from_buffer_copy(
digest.encode('utf-8'))
binascii.a2b_hex(digest.encode('utf-8')))
component_list[idx].file_path = file_path.encode("utf-8")
component_list[idx].component_addr = \
('/%s' % component[0]).encode("utf-8")
component_list[idx].version = component[4].encode("utf-8")
component_list[idx].size = 0
component_list[idx].transfer_id = int(component[1])
component_list[idx].original_size = os.path.getsize(file_path)
component_list[idx].size = os.path.getsize(file_path)
component_list[idx].id = int(component[1])
if component[3] == 1:
component_list[idx].original_size = os.path.getsize(file_path)
else:
component_list[idx].original_size = 0
component_list[idx].res_type = int(component[2])
component_list[idx].type_str = int(component[3])
component_list[idx].type = int(component[3])
component_list[idx].flags = IS_DEL
idx += 1
return component_list
@ -197,16 +204,17 @@ def get_head_list(component_count, head_value_list):
head_list.software_version = head_value_list[2].encode("utf-8")
head_list.date = head_value_list[3].encode("utf-8")
head_list.time = head_value_list[4].encode("utf-8")
head_list.describe_package_id = c_char_p("update/info.bin".encode())
return head_list
def get_tools_component_list(count, opera_script_dict):
"""
Get the list of component information according to
Get the list of component information according to
the component information structure.
:param count: number of components
:param opera_script_dict: script file name and path dict
:return component_list: list of component information.
:return component_list: list of component information.
If exception occurs, return False.
"""
pkg_components = PkgComponent * count
@ -305,10 +313,16 @@ def create_build_tools_zip(lib):
for each in each_value:
opera_script_dict[each[1].name] = each[0]
count += 1
head_list = get_tools_head_list(count + 2)
# other_file_count --> 1(updater_binary) + 1(loadScript.us)
other_file_count = 2
count += other_file_count
if OPTIONS_MANAGER.register_script_file_obj is not None:
count += 1
head_list = get_tools_head_list(count)
component_list, num = \
get_tools_component_list(count + 2, opera_script_dict)
get_tools_component_list(count, opera_script_dict)
total_script_file_obj = OPTIONS_MANAGER.total_script_file_obj
register_script_file_obj = OPTIONS_MANAGER.register_script_file_obj
update_exe_path = os.path.join(OPTIONS_MANAGER.target_package_dir,
UPDATE_EXE_FILE_NAME)
if not os.path.exists(update_exe_path):
@ -325,6 +339,13 @@ def create_build_tools_zip(lib):
total_script_file_obj.name.encode("utf-8")
component_list[num + 1].component_addr = \
TOTAL_SCRIPT_FILE_NAME.encode("utf-8")
if OPTIONS_MANAGER.register_script_file_obj is not None:
component_list[num + 2].file_path = \
register_script_file_obj.name.encode("utf-8")
component_list[num + 2].component_addr = \
REGISTER_SCRIPT_FILE_NAME.encode("utf-8")
lib.CreatePackage(
pointer(head_list), component_list, file_save_patch,
OPTIONS_MANAGER.private_key.encode("utf-8"))
@ -429,12 +450,14 @@ def get_hash_content(file_path, hash_algorithm):
raise RuntimeError
process_obj = subprocess.Popen(
cmd, shell=False, stdout=subprocess.PIPE, stderr=subprocess.STDOUT)
hash_content = ''
while process_obj.poll() is None:
line = process_obj.stdout.readline()
line = line.strip()
if line:
hash_content = line.decode(encoding='gbk').split(' ')[0]
process_obj.wait()
hash_content = \
process_obj.stdout.read().decode(encoding='gbk').split(' ')[0]
if len(hash_content) != HASH_CONTENT_LEN_DICT.get(hash_algorithm):
UPDATE_LOGGER.print_log(
"Get hash content failed! The length of the hash_content is 0!",
UPDATE_LOGGER.ERROR_LOG)
raise RuntimeError
if process_obj.returncode == 0:
UPDATE_LOGGER.print_log(
"Get hash content success! path: %s" % file_path)

View File

@ -30,13 +30,14 @@ from ctypes import cdll
from cryptography.hazmat.primitives import hashes
from log_exception import UPDATE_LOGGER
operation_path = os.getcwd()
operation_path = os.path.dirname(os.path.realpath(__file__))
PRODUCT = 'hi3516'
BUILD_TOOLS_FILE_NAME = 'build_tools.zip'
UPDATE_EXE_FILE_NAME = "updater_binary"
SCRIPT_KEY_LIST = ['prelude', 'verse', 'refrain', 'ending']
TOTAL_SCRIPT_FILE_NAME = "loadScript.us"
REGISTER_SCRIPT_FILE_NAME = "registerCmd.us"
SCRIPT_FILE_NAME = '-script.us'
UPDATER_CONFIG = "updater_config"
@ -64,6 +65,7 @@ CHUNK_TYPE_CRC32 = 0xCAC4
HASH_ALGORITHM_DICT = {'sha256': hashes.SHA256, 'sha384': hashes.SHA384}
LINUX_HASH_ALGORITHM_DICT = {'sha256': 'sha256sum', 'sha384': 'sha384sum'}
HASH_CONTENT_LEN_DICT = {'sha256': 64, 'sha384': 96}
COMPONENT_INFO_INNIT = ['', '000', '00', '0', '0o00']
@ -160,6 +162,8 @@ class OptionsManager:
self.opera_script_file_name_dict[each] = []
self.total_script_file_obj = None
self.register_script_file_obj = None
# Update package parameters
self.update_bin_obj = None
self.build_tools_zip_obj = None
@ -404,6 +408,8 @@ def clear_options():
OPTIONS_MANAGER.opera_script_file_name_dict[each] = []
OPTIONS_MANAGER.total_script_file_obj = None
OPTIONS_MANAGER.register_script_file_obj = None
# Update package parameters
OPTIONS_MANAGER.update_bin_obj = None
OPTIONS_MANAGER.build_tools_zip_obj = None
@ -437,6 +443,10 @@ def clear_resource(err_clear=False):
if total_script_file_obj is not None:
total_script_file_obj.close()
register_script_file_obj = OPTIONS_MANAGER.register_script_file_obj
if register_script_file_obj is not None:
register_script_file_obj.close()
full_image_file_obj_list = OPTIONS_MANAGER.full_image_file_obj_list
if len(full_image_file_obj_list) != 0:
for each_full_obj in full_image_file_obj_list:

View File

@ -13,9 +13,16 @@
# 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 tempfile
from script_generator import Script
from log_exception import UPDATE_LOGGER
from script_generator import EndingScript
from script_generator import RefrainScript
from script_generator import VerseScript
from script_generator import PreludeScript
from utils import SCRIPT_KEY_LIST
from utils import OPTIONS_MANAGER
from utils import REGISTER_SCRIPT_FILE_NAME
def create_vendor_script_class():
@ -25,6 +32,8 @@ def create_vendor_script_class():
SCRIPT_KEY_LIST is the stage list in Opera mode.
If needed, rewrite this function to create a Vendor{Opera}Script object
class and return the object. Sample code is as follows:
ExtensionCmdRegister().generate_register_cmd_script()
prelude_script = VendorPreludeScript()
verse_script = VendorVerseScript()
refrain_script = VendorRefrainScript()
@ -37,21 +46,55 @@ def create_vendor_script_class():
return opera_obj_list
class VendorPreludeScript(Script):
class VendorPreludeScript(PreludeScript):
def __init__(self):
super().__init__()
class VendorVerseScript(Script):
class VendorVerseScript(VerseScript):
def __init__(self):
super().__init__()
class VendorRefrainScript(Script):
class VendorRefrainScript(RefrainScript):
def __init__(self):
super().__init__()
class VendorEndingScript(Script):
class VendorEndingScript(EndingScript):
def __init__(self):
super().__init__()
class ExtensionCmdRegister:
def __init__(self):
"""
ExtensionCmdRegister for vendor extended command registration.
self.__cmd_in_so_dict needs the dict of extension command and
the corresponding so path.
like: self.__cmd_in_so_dict = \
{"/data/updater/libtest.z.so":
["extension_cmd1", "extension_cmd2"],
"/data/updater/libtest2.z.so": ["extension_cmd3"],
}
"""
self.__cmd_in_so_dict = {}
def generate_register_cmd_script(self):
"""
Generate the register script.
"""
if len(self.__cmd_in_so_dict.keys()) != 0:
content_list = []
for each_so_path, each_cmds_list in self.__cmd_in_so_dict.items():
for each_cmd in each_cmds_list:
each_content = \
'RegisterCmder("%s" , ' \
'"%s");' % (each_cmd, each_so_path)
content_list.append(each_content)
register_script = tempfile.NamedTemporaryFile(mode='w+')
register_script.write('\n'.join(content_list))
register_script.seek(0)
OPTIONS_MANAGER.register_script_file_obj = register_script
UPDATE_LOGGER.print_log("%s generation complete!" %
REGISTER_SCRIPT_FILE_NAME)