• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1#!/usr/bin/env python3
2# -*- coding: utf-8 -*-
3
4# Copyright (c) 2021 Huawei Device Co., Ltd.
5# Licensed under the Apache License, Version 2.0 (the "License");
6# you may not use this file except in compliance with the License.
7# You may obtain a copy of the License at
8#
9# http://www.apache.org/licenses/LICENSE-2.0
10#
11# Unless required by applicable law or agreed to in writing, software
12# distributed under the License is distributed on an "AS IS" BASIS,
13# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14# See the License for the specific language governing permissions and
15# limitations under the License.
16"""
17Description : Defining constants, common interface
18"""
19import argparse
20import json
21import os
22import shutil
23import tempfile
24import zipfile
25from collections import OrderedDict
26from copy import copy
27from ctypes import cdll
28from cryptography.hazmat.primitives import hashes
29from log_exception import UPDATE_LOGGER
30import xmltodict
31from build_pkcs7 import sign_ota_package
32
33operation_path = os.path.dirname(os.path.realpath(__file__))
34PRODUCT = 'hi3516'
35BUILD_TOOLS_FILE_NAME = 'build_tools.zip'
36UPDATE_EXE_FILE_NAME = "updater_binary"
37
38SCRIPT_KEY_LIST = ['prelude', 'verse', 'refrain', 'ending']
39TOTAL_SCRIPT_FILE_NAME = "loadScript.us"
40REGISTER_SCRIPT_FILE_NAME = "registerCmd.us"
41SCRIPT_FILE_NAME = '-script.us'
42
43UPDATER_CONFIG = "updater_config"
44XML_FILE_PATH = "updater_specified_config.xml"
45SO_PATH = os.path.join(operation_path, 'lib/libpackage.so')
46SO_PATH_L1 = os.path.join(operation_path, 'lib/libpackageL1.so')
47DIFF_EXE_PATH = os.path.join(operation_path, 'lib/diff')
48E2FSDROID_PATH = os.path.join(operation_path, 'lib/e2fsdroid')
49MISC_INFO_PATH = "misc_info.txt"
50VERSION_MBN_PATH = "VERSION.mbn"
51BOARD_LIST_PATH = "BOARD.list"
52EXTEND_COMPONENT_LIST = ["version_list", "board_list"]
53EXTEND_OPTIONAL_COMPONENT_LIST = ["partitions_file"]
54PARTITION_FILE = "partitions_file"
55IGNORED_PARTITION_LIST = ['fastboot', 'boot', 'kernel', 'misc',
56                          'updater', 'userdata']
57
58HASH_ALGORITHM_DICT = {'sha256': hashes.SHA256, 'sha384': hashes.SHA384}
59LINUX_HASH_ALGORITHM_DICT = {'sha256': 'sha256sum', 'sha384': 'sha384sum'}
60HASH_CONTENT_LEN_DICT = {'sha256': 64, 'sha384': 96}
61
62COMPONENT_INFO_INNIT = ['', '000', '00', '0', '0o00']
63
64ON_SERVER = "ON_SERVER"
65
66EXTEND_VALUE = 512
67
68FILE_MAP_ZERO_KEY = "__ZERO"
69FILE_MAP_NONZERO_KEY = "__NONZERO"
70FILE_MAP_COPY_KEY = "__COPY"
71
72MAX_BLOCKS_PER_GROUP = BLOCK_LIMIT = 1024
73PER_BLOCK_SIZE = 4096
74TWO_STEP = "updater"
75
76VERSE_SCRIPT_EVENT = 0
77INC_IMAGE_EVENT = 1
78SIGN_PACKAGE_EVENT = 2
79
80# Image file can not support update.
81FORBIDEN_UPDATE_IMAGE_LIST = ["updater_boot", "updater_b", "ptable"]
82
83# 1000000: max number of function recursion depth
84MAXIMUM_RECURSION_DEPTH = 1000000
85
86
87def singleton(cls):
88    _instance = {}
89
90    def _singleton(*args, **kargs):
91        if cls not in _instance:
92            _instance[cls] = cls(*args, **kargs)
93        return _instance[cls]
94
95    return _singleton
96
97
98class ExtInit:
99    """
100    Init event for ext
101    """
102
103    def __init__(self):
104        self.funs = []
105
106    def reg_event(self, evevt_id, funs):
107            self.funs.append([evevt_id, funs])
108            UPDATE_LOGGER.print_log(
109                'register event %s: %s' % (evevt_id, funs.__name__))
110
111    def invoke_event(self, evevt_id):
112        UPDATE_LOGGER.print_log(self.funs)
113        for event in self.funs:
114            funs = event[1]
115            if event[0] == evevt_id and funs is not None:
116                UPDATE_LOGGER.print_log(
117                    'invoke event %s: %s' % (evevt_id, funs.__name__))
118                return funs
119        return False
120
121
122@singleton
123class OptionsManager:
124    """
125    Options management class
126    """
127
128    def __init__(self):
129        self.init = ExtInit()
130        self.parser = argparse.ArgumentParser()
131
132        # Own parameters
133        self.product = None
134
135        # Entry parameters
136        self.source_package = None
137        self.target_package = None
138        self.update_package = None
139        self.unpack_package_path = None
140        self.no_zip = False
141        self.partition_file = None
142        self.signing_algorithm = None
143        self.hash_algorithm = None
144        self.private_key = None
145        self.not_l2 = False
146        self.signing_length = 256
147        self.xml_path = None
148        self.sd_card = False
149
150        self.make_dir_path = None
151
152        # Parsed package parameters
153        self.target_package_dir = None
154        self.target_package_config_dir = None
155        self.target_package_temp_obj = None
156        self.misc_info_dict = {}
157        self.version_mbn_file_path = None
158        self.version_mbn_content = None
159        self.board_list_file_path = None
160        self.board_list_content = None
161
162        self.source_package_dir = None
163        self.source_package_temp_obj = None
164
165        # XML parsing parameters
166        self.head_info_list = []
167        self.component_info_dict = {}
168        self.full_img_list = []
169        self.full_img_name_list = []
170        self.incremental_img_list = []
171        self.incremental_img_name_list = []
172        self.target_package_version = None
173        self.source_package_version = None
174        self.two_step = False
175        self.full_image_path_list = []
176
177        self.partition_file_obj = None
178
179        # Full processing parameters
180        self.full_image_content_len_list = []
181        self.full_image_file_obj_list = []
182
183        # Incremental processing parameters
184        self.incremental_content_len_list = []
185        self.incremental_image_file_obj_list = []
186        self.incremental_temp_file_obj_list = []
187        self.src_image = None
188        self.tgt_image = None
189
190        # Script parameters
191        self.opera_script_file_name_dict = {}
192        for each in SCRIPT_KEY_LIST:
193            self.opera_script_file_name_dict[each] = []
194        self.total_script_file_obj = None
195
196        self.register_script_file_obj = None
197
198        # Update package parameters
199        self.update_bin_obj = None
200        self.build_tools_zip_obj = None
201        self.update_package_file_path = None
202        self.signed_package = None
203
204
205OPTIONS_MANAGER = OptionsManager()
206
207
208def unzip_package(package_path, origin='target'):
209    """
210    Decompress the zip package.
211    :param package_path: zip package path
212    :param origin: package origin, which indicates
213                whether the zip package is a source package or target package
214    :return: Temporary directory (tmp_dir) and zip_data package;
215            false if an exception occurs.
216    """
217    try:
218        tmp_dir_obj = tempfile.TemporaryDirectory(prefix="%sfiles-" % origin)
219        tmp_dir = tmp_dir_obj.name
220
221        zf_obj = zipfile.ZipFile(package_path)
222        for name in zf_obj.namelist():
223            if name.endswith('/'):
224                os.mkdir(os.path.join(tmp_dir, name))
225            else:
226                ext_filename = os.path.join(
227                    tmp_dir, name)
228                with open(ext_filename, 'wb') as f_w:
229                    f_w.write(zf_obj.read(name))
230    except OSError:
231        UPDATE_LOGGER.print_log(
232            "Unzip package failed! path: %s" % package_path,
233            log_type=UPDATE_LOGGER.ERROR_LOG)
234        return False, False
235    tmp_dir_list = os.listdir(tmp_dir)
236    if len(tmp_dir_list) == 1:
237        unzip_dir = os.path.join(tmp_dir, tmp_dir_list[0])
238        if UPDATER_CONFIG not in \
239                os.listdir(unzip_dir):
240            UPDATE_LOGGER.print_log(
241                'Unsupported zip package structure!', UPDATE_LOGGER.ERROR_LOG)
242            return False, False
243    elif UPDATER_CONFIG in tmp_dir_list:
244        unzip_dir = tmp_dir
245    else:
246        UPDATE_LOGGER.print_log(
247            'Unsupported zip package structure!', UPDATE_LOGGER.ERROR_LOG)
248        return False, False
249    UPDATE_LOGGER.print_log(
250        '%s package unzip complete! path: %s' % (origin.title(), unzip_dir))
251
252    return tmp_dir_obj, unzip_dir
253
254
255def split_img_name(image_path):
256    """
257    Split the image name by image path
258    :return image name
259    """
260    tmp_path = image_path
261    str_list = tmp_path.split("/")
262
263    return str_list[-1]
264
265
266def get_update_config_softversion(mbn_dir, head_info_dict):
267    soft_version_file = head_info_dict.get('softVersionFile')
268    if soft_version_file is not None:
269        mbn_path = os.path.join(mbn_dir, soft_version_file)
270        if os.path.exists(mbn_path):
271            with open(mbn_path, 'r') as mbn_file:
272                head_info_dict['info']["@softVersion"] = mbn_file.read()
273
274
275def parse_update_config(xml_path):
276    """
277    Parse the XML configuration file.
278    :param xml_path: XML configuration file path
279    :return head_info_dict: header information dict of the update package
280            component_info_dict: component information dict
281            full_img_list: full image list
282            incremental_img_list: incremental image list
283    """
284    two_step = False
285    if os.path.exists(xml_path):
286        with open(xml_path, 'r') as xml_file:
287            xml_str = xml_file.read()
288    else:
289        UPDATE_LOGGER.print_log("XML file does not exist! xml path: %s" %
290                                xml_path, UPDATE_LOGGER.ERROR_LOG)
291        ret_params = [False, False, False, False, False, False, False]
292        return ret_params
293    xml_content_dict = xmltodict.parse(xml_str, encoding='utf-8')
294    package_dict = xml_content_dict.get('package', {})
295    get_update_config_softversion(OPTIONS_MANAGER.target_package_dir, package_dict.get('head', {}))
296    head_dict = package_dict.get('head', {}).get('info')
297    package_version = head_dict.get("@softVersion")
298    # component
299    component_info = package_dict.get('group', {}).get('component')
300    head_list = list(head_dict.values())
301    head_list.pop()
302    whole_list = []
303    difference_list = []
304    component_dict = {}
305    full_image_path_list = []
306
307    if not OPTIONS_MANAGER.not_l2:
308        expand_component(component_dict)
309    if isinstance(component_info, OrderedDict):
310        component_info = [component_info]
311    if component_info is None:
312        ret_params = [[], {}, [], [], '', [], False]
313        return ret_params
314    for component in component_info:
315        component_list = list(component.values())
316        component_list.pop()
317        component_dict[component['@compAddr']] = component_list
318
319        if component['@compAddr'] in (whole_list + difference_list):
320            UPDATE_LOGGER.print_log("This component %s  repeats!" %
321                                    component['@compAddr'],
322                                    UPDATE_LOGGER.ERROR_LOG)
323            ret_params = [False, False, False, False, False, False, False]
324            return ret_params
325
326        if component['@compType'] == '0':
327            whole_list.append(component['@compAddr'])
328            OPTIONS_MANAGER.full_img_name_list.\
329                append(split_img_name(component['#text']))
330            tem_path = os.path.join(OPTIONS_MANAGER.target_package_dir,
331                                    component.get("#text", None))
332            full_image_path_list.append(tem_path)
333        elif component['@compType'] == '1':
334            difference_list.append(component['@compAddr'])
335            OPTIONS_MANAGER.incremental_img_name_list.\
336                append(split_img_name(component['#text']))
337
338        if component['@compAddr'] == TWO_STEP:
339            two_step = True
340
341    UPDATE_LOGGER.print_log('XML file parsing completed!')
342    ret_params = [head_list, component_dict,
343                  whole_list, difference_list, package_version,
344                  full_image_path_list, two_step]
345    return ret_params
346
347
348def partitions_conversion(data):
349    """
350    Convert the start or length data in the partition table through
351    multiply 1024 * 1024 and return the data.
352    :param data: start or length data
353    :return :
354    """
355    if data == '0':
356        return 0
357    elif data.endswith('M'):
358        return int(data[0:-1]) * 1024 * 1024 // 512
359    else:
360        return False
361
362
363def parse_partition_file_xml(xml_path):
364    """
365    Parse the XML configuration file.
366    :param xml_path: XML configuration file path
367    :return part_json: partition table information in JSON format
368    """
369    if os.path.exists(xml_path):
370        with open(xml_path, 'r') as xml_file:
371            xml_str = xml_file.read()
372    else:
373        UPDATE_LOGGER.print_log("XML file does not exist! xml path: %s" %
374                                xml_path, UPDATE_LOGGER.ERROR_LOG)
375        return False, False, False
376    partitions_list = []
377    partitions_file_path_list = []
378    xml_content_dict = xmltodict.parse(xml_str, encoding='utf-8')
379    part_list = xml_content_dict['Partition_Info']['Part']
380    new_part_list = []
381    for i, part in enumerate(part_list):
382        start_value = partitions_conversion(part.get('@Start'))
383        length_value = partitions_conversion(part.get('@Length'))
384        if start_value is False or length_value is False:
385            UPDATE_LOGGER.print_log(
386                "Partition file parsing failed! part_name: %s, xml_path: %s" %
387                (part.get('@PartitionName'), xml_path),
388                UPDATE_LOGGER.ERROR_LOG)
389            return False, False, False
390
391        if part.get('@PartitionName') not in IGNORED_PARTITION_LIST:
392            partitions_list.append(part.get('@PartitionName'))
393            partitions_file_path_list.append(
394                os.path.join(OPTIONS_MANAGER.target_package_dir,
395                             "%s.img" % part.get('@PartitionName')))
396        part_dict = {'start': start_value,
397                     'length': length_value,
398                     'partName': part.get('@PartitionName'),
399                     'fsType': part.get('@FlashType')}
400        new_part_list.append(part_dict)
401    part_json = json.dumps(new_part_list)
402    part_json = '{"Partition": %s}' % part_json
403    file_obj = tempfile.NamedTemporaryFile(
404        dir=OPTIONS_MANAGER.target_package_dir, prefix="partition_file-", mode='wb')
405    file_obj.write(part_json.encode())
406    file_obj.seek(0)
407    return file_obj, partitions_list, partitions_file_path_list
408
409
410def expand_component(component_dict):
411    """
412    Append components such as VERSION.mbn and board list.
413    :param component_dict: component information dict
414    :return:
415    """
416    if OPTIONS_MANAGER.partition_file is not None:
417        extend_component_list = \
418            EXTEND_COMPONENT_LIST + EXTEND_OPTIONAL_COMPONENT_LIST
419    else:
420        extend_component_list = EXTEND_COMPONENT_LIST
421    for each in extend_component_list:
422        tmp_info_list = copy(COMPONENT_INFO_INNIT)
423        tmp_info_list[0] = each
424        component_dict[each] = tmp_info_list
425
426
427def clear_options():
428    """
429    Clear OPTIONS_MANAGER.
430    """
431    OPTIONS_MANAGER.product = None
432
433    # Entry parameters
434    OPTIONS_MANAGER.source_package = None
435    OPTIONS_MANAGER.target_package = None
436    OPTIONS_MANAGER.update_package = None
437    OPTIONS_MANAGER.no_zip = False
438    OPTIONS_MANAGER.partition_file = None
439    OPTIONS_MANAGER.signing_algorithm = None
440    OPTIONS_MANAGER.hash_algorithm = None
441    OPTIONS_MANAGER.private_key = None
442    OPTIONS_MANAGER.not_l2 = False
443    OPTIONS_MANAGER.signing_length = 256
444    OPTIONS_MANAGER.xml_path = None
445    OPTIONS_MANAGER.sd_card = False
446
447    OPTIONS_MANAGER.full_image_path_list = []
448
449    OPTIONS_MANAGER.make_dir_path = None
450
451    # Parsed package parameters
452    OPTIONS_MANAGER.target_package_dir = None
453    OPTIONS_MANAGER.target_package_config_dir = None
454    OPTIONS_MANAGER.target_package_temp_obj = None
455    OPTIONS_MANAGER.misc_info_dict = {}
456    OPTIONS_MANAGER.version_mbn_file_path = None
457    OPTIONS_MANAGER.version_mbn_content = None
458    OPTIONS_MANAGER.board_list_file_path = None
459    OPTIONS_MANAGER.board_list_content = None
460
461    OPTIONS_MANAGER.source_package_dir = None
462    OPTIONS_MANAGER.source_package_temp_obj = None
463
464    # XML parsing parameters
465    OPTIONS_MANAGER.head_info_list = []
466    OPTIONS_MANAGER.component_info_dict = {}
467    OPTIONS_MANAGER.full_img_list = []
468    OPTIONS_MANAGER.incremental_img_list = []
469    OPTIONS_MANAGER.target_package_version = None
470    OPTIONS_MANAGER.source_package_version = None
471    OPTIONS_MANAGER.partition_file_obj = None
472
473    # Global processing parameters
474    OPTIONS_MANAGER.full_image_content_len_list = []
475    OPTIONS_MANAGER.full_image_file_obj_list = []
476
477    # Incremental processing parameters
478    OPTIONS_MANAGER.incremental_content_len_list = []
479    OPTIONS_MANAGER.incremental_image_file_obj_list = []
480    OPTIONS_MANAGER.incremental_temp_file_obj_list = []
481
482    # Script parameters
483    OPTIONS_MANAGER.opera_script_file_name_dict = {}
484    for each in SCRIPT_KEY_LIST:
485        OPTIONS_MANAGER.opera_script_file_name_dict[each] = []
486    OPTIONS_MANAGER.total_script_file_obj = None
487
488    OPTIONS_MANAGER.register_script_file_obj = None
489
490    # Update package parameters
491    OPTIONS_MANAGER.update_bin_obj = None
492    OPTIONS_MANAGER.build_tools_zip_obj = None
493    OPTIONS_MANAGER.update_package_file_path = None
494
495
496def clear_resource(err_clear=False):
497    """
498    Clear resources, close temporary files, and clear temporary paths.
499    :param err_clear: whether to clear errors
500    :return:
501    """
502    target_package_temp_obj = OPTIONS_MANAGER.target_package_temp_obj
503    if target_package_temp_obj is not None:
504        target_package_temp_obj.cleanup()
505    source_package_temp_obj = OPTIONS_MANAGER.source_package_temp_obj
506    if source_package_temp_obj is not None:
507        source_package_temp_obj.cleanup()
508
509    partition_file_obj = OPTIONS_MANAGER.partition_file_obj
510    if partition_file_obj is not None:
511        partition_file_obj.close()
512
513    build_tools_zip_obj = OPTIONS_MANAGER.build_tools_zip_obj
514    if build_tools_zip_obj is not None:
515        build_tools_zip_obj.close()
516    update_bin_obj = OPTIONS_MANAGER.update_bin_obj
517    if update_bin_obj is not None:
518        update_bin_obj.close()
519    total_script_file_obj = OPTIONS_MANAGER.total_script_file_obj
520    if total_script_file_obj is not None:
521        total_script_file_obj.close()
522
523    register_script_file_obj = OPTIONS_MANAGER.register_script_file_obj
524    if register_script_file_obj is not None:
525        register_script_file_obj.close()
526
527    full_image_file_obj_list = OPTIONS_MANAGER.full_image_file_obj_list
528    if len(full_image_file_obj_list) != 0:
529        for each_full_obj in full_image_file_obj_list:
530            each_full_obj.close()
531
532    clear_file_obj(err_clear)
533    clear_options()
534
535
536def clear_file_obj(err_clear):
537    """
538    Clear resources and temporary file objects.
539    :param err_clear: whether to clear errors
540    :return:
541    """
542    incremental_temp_file_obj_list = \
543        OPTIONS_MANAGER.incremental_temp_file_obj_list
544    if len(incremental_temp_file_obj_list) != 0:
545        for each_incremental_temp_obj in incremental_temp_file_obj_list:
546            if each_incremental_temp_obj is not None:
547                each_incremental_temp_obj.close()
548    incremental_image_file_obj_list = \
549        OPTIONS_MANAGER.incremental_image_file_obj_list
550    if len(incremental_image_file_obj_list) != 0:
551        for each_incremental_obj in incremental_image_file_obj_list:
552            if each_incremental_obj is not None:
553                each_incremental_obj.close()
554    opera_script_file_name_dict = OPTIONS_MANAGER.opera_script_file_name_dict
555    for each_value in opera_script_file_name_dict.values():
556        for each in each_value:
557            each[1].close()
558    if err_clear:
559        make_dir_path = OPTIONS_MANAGER.make_dir_path
560        if make_dir_path is not None and os.path.exists(make_dir_path):
561            shutil.rmtree(make_dir_path)
562        update_package_file_path = OPTIONS_MANAGER.update_package_file_path
563        if update_package_file_path is not None and \
564                os.path.exists(update_package_file_path):
565            os.remove(update_package_file_path)
566        UPDATE_LOGGER.print_log(
567            'Exception occurred, Resource cleaning completed!')
568    else:
569        UPDATE_LOGGER.print_log('Resource cleaning completed!')
570
571
572def get_file_content(file_path, file_name=None):
573    """
574    Read the file content.
575    :param file_path: file path
576    :param file_name: file name
577    :return: file content
578    """
579    if not os.path.exists(file_path):
580        UPDATE_LOGGER.print_log(
581            "%s is not exist! path: %s" % (file_name, file_path),
582            log_type=UPDATE_LOGGER.ERROR_LOG)
583        return False
584    with open(file_path, 'r') as r_f:
585        file_content = r_f.read()
586    UPDATE_LOGGER.print_log(
587        "%s file parsing complete! path: %s" % (file_name, file_path))
588    return file_content
589
590
591def get_update_info():
592    """
593    Parse the configuration file to obtain the update information.
594    :return: update information if any; false otherwise.
595    """
596    if not OPTIONS_MANAGER.not_l2:
597        OPTIONS_MANAGER.version_mbn_file_path = os.path.join(
598            OPTIONS_MANAGER.target_package_config_dir, VERSION_MBN_PATH)
599        version_mbn_content = \
600            get_file_content(
601                OPTIONS_MANAGER.version_mbn_file_path, os.path.basename(
602                    os.path.join(OPTIONS_MANAGER.target_package_config_dir,
603                                 VERSION_MBN_PATH)))
604        if version_mbn_content is False:
605            UPDATE_LOGGER.print_log(
606                "Get version mbn content failed!",
607                log_type=UPDATE_LOGGER.ERROR_LOG)
608            return False
609        OPTIONS_MANAGER.version_mbn_content = version_mbn_content
610        OPTIONS_MANAGER.board_list_file_path = os.path.join(
611            OPTIONS_MANAGER.target_package_config_dir, BOARD_LIST_PATH)
612        board_list_content = \
613            get_file_content(
614                OPTIONS_MANAGER.board_list_file_path, os.path.basename(
615                    os.path.join(OPTIONS_MANAGER.target_package_config_dir,
616                                 BOARD_LIST_PATH)))
617        if board_list_content is False:
618            UPDATE_LOGGER.print_log(
619                "Get board list content failed!",
620                log_type=UPDATE_LOGGER.ERROR_LOG)
621            return False
622        OPTIONS_MANAGER.board_list_content = board_list_content
623
624    if OPTIONS_MANAGER.xml_path is None:
625        xml_file_path = os.path.join(
626            OPTIONS_MANAGER.target_package_config_dir, XML_FILE_PATH)
627    else:
628        xml_file_path = OPTIONS_MANAGER.xml_path
629
630    # Parse the XML configuration file.
631    head_info_list, component_info_dict, \
632        full_img_list, incremental_img_list, \
633        OPTIONS_MANAGER.target_package_version, \
634        OPTIONS_MANAGER.full_image_path_list, \
635        OPTIONS_MANAGER.two_step = \
636        parse_update_config(xml_file_path)
637    if head_info_list is False or component_info_dict is False or \
638            full_img_list is False or incremental_img_list is False:
639        UPDATE_LOGGER.print_log(
640            "Get parse update config xml failed!",
641            log_type=UPDATE_LOGGER.ERROR_LOG)
642        return False
643    OPTIONS_MANAGER.head_info_list, OPTIONS_MANAGER.component_info_dict, \
644        OPTIONS_MANAGER.full_img_list, OPTIONS_MANAGER.incremental_img_list = \
645        head_info_list, component_info_dict, \
646        full_img_list, incremental_img_list
647    return True
648
649
650def sign_package():
651    return sign_ota_package(
652        OPTIONS_MANAGER.update_package_file_path,
653        OPTIONS_MANAGER.signed_package,
654        OPTIONS_MANAGER.private_key)