15f9996aaSopenharmony_ci#!/usr/bin/env python
25f9996aaSopenharmony_ci# coding: utf-8
35f9996aaSopenharmony_ci# Copyright (c) 2021 Huawei Device Co., Ltd.
45f9996aaSopenharmony_ci# Licensed under the Apache License, Version 2.0 (the "License");
55f9996aaSopenharmony_ci# you may not use this file except in compliance with the License.
65f9996aaSopenharmony_ci# You may obtain a copy of the License at
75f9996aaSopenharmony_ci#
85f9996aaSopenharmony_ci#     http://www.apache.org/licenses/LICENSE-2.0
95f9996aaSopenharmony_ci#
105f9996aaSopenharmony_ci# Unless required by applicable law or agreed to in writing, software
115f9996aaSopenharmony_ci# distributed under the License is distributed on an "AS IS" BASIS,
125f9996aaSopenharmony_ci# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
135f9996aaSopenharmony_ci# See the License for the specific language governing permissions and
145f9996aaSopenharmony_ci# limitations under the License.
155f9996aaSopenharmony_ci
165f9996aaSopenharmony_ciimport json
175f9996aaSopenharmony_ciimport os
185f9996aaSopenharmony_ciimport sys
195f9996aaSopenharmony_ciimport subprocess
205f9996aaSopenharmony_ciimport shutil
215f9996aaSopenharmony_ciimport tempfile
225f9996aaSopenharmony_ci
235f9996aaSopenharmony_ci
245f9996aaSopenharmony_cisys.path.append(
255f9996aaSopenharmony_ci    os.path.dirname(os.path.dirname(os.path.dirname(os.path.dirname(
265f9996aaSopenharmony_ci        os.path.abspath(__file__))))))
275f9996aaSopenharmony_cifrom build_scripts.build import find_top
285f9996aaSopenharmony_ci
295f9996aaSopenharmony_ci
305f9996aaSopenharmony_cidef run_cmd(cmd: str):
315f9996aaSopenharmony_ci    res = subprocess.Popen(cmd.split(), stdout=subprocess.PIPE,
325f9996aaSopenharmony_ci                           stderr=subprocess.PIPE)
335f9996aaSopenharmony_ci    sout, serr = res.communicate()
345f9996aaSopenharmony_ci
355f9996aaSopenharmony_ci    return res.pid, res.returncode, sout, serr
365f9996aaSopenharmony_ci
375f9996aaSopenharmony_ci
385f9996aaSopenharmony_cidef build_rootdir(src_dir: str) -> str:
395f9996aaSopenharmony_ci    tmp_dir = tempfile.mkdtemp(prefix="tmp")
405f9996aaSopenharmony_ci    index = src_dir.rfind('/')
415f9996aaSopenharmony_ci    root_dir = "%sroot" % src_dir[:index + 1]
425f9996aaSopenharmony_ci
435f9996aaSopenharmony_ci    if root_dir:
445f9996aaSopenharmony_ci        shutil.rmtree(tmp_dir)
455f9996aaSopenharmony_ci        shutil.copytree(root_dir, tmp_dir, symlinks=True)
465f9996aaSopenharmony_ci    tmp_dir_system = os.path.join(tmp_dir, "system")
475f9996aaSopenharmony_ci    shutil.rmtree(tmp_dir_system, ignore_errors=True)
485f9996aaSopenharmony_ci    shutil.copytree(src_dir, tmp_dir_system, symlinks=True)
495f9996aaSopenharmony_ci    return tmp_dir
505f9996aaSopenharmony_ci
515f9996aaSopenharmony_ci
525f9996aaSopenharmony_cidef load_config(config_file: str) -> list:
535f9996aaSopenharmony_ci    mk_configs = []
545f9996aaSopenharmony_ci    with open(config_file, "r") as file:
555f9996aaSopenharmony_ci        for line in file:
565f9996aaSopenharmony_ci            line = line.strip()
575f9996aaSopenharmony_ci            if not line or line.startswith("#"):
585f9996aaSopenharmony_ci                continue
595f9996aaSopenharmony_ci            mk_configs.append(line)
605f9996aaSopenharmony_ci    mk_configs = " ".join(mk_configs)
615f9996aaSopenharmony_ci    if "ext4" in mk_configs:
625f9996aaSopenharmony_ci        fs_type = "ext4"
635f9996aaSopenharmony_ci        mkfs_tools = "mkextimage.py"
645f9996aaSopenharmony_ci    elif "f2fs" in mk_configs:
655f9996aaSopenharmony_ci        mkfs_tools = "mkf2fsimage.py"
665f9996aaSopenharmony_ci        fs_type = "f2fs"
675f9996aaSopenharmony_ci    elif "cpio" in mk_configs:
685f9996aaSopenharmony_ci        mkfs_tools = "mkcpioimage.py"
695f9996aaSopenharmony_ci        fs_type = "cpio"
705f9996aaSopenharmony_ci    else:
715f9996aaSopenharmony_ci        print("not support filesystem type!!")
725f9996aaSopenharmony_ci        sys.exit(1)
735f9996aaSopenharmony_ci    return mkfs_tools, mk_configs, fs_type
745f9996aaSopenharmony_ci
755f9996aaSopenharmony_ci
765f9996aaSopenharmony_cidef verify_ret(res: list):
775f9996aaSopenharmony_ci    if res[1]:
785f9996aaSopenharmony_ci        print(" ".join(["pid ", str(res[0]), " ret ", str(res[1]), "\n",
795f9996aaSopenharmony_ci                        res[2].decode(), res[3].decode()]))
805f9996aaSopenharmony_ci        print("MkImages failed errno: %s" % str(res[1]))
815f9996aaSopenharmony_ci        sys.exit(2)
825f9996aaSopenharmony_ci
835f9996aaSopenharmony_ci
845f9996aaSopenharmony_cidef sparse_img2simg(is_sparse: str, device: str):
855f9996aaSopenharmony_ci    # we don't support sparse in mktools.
865f9996aaSopenharmony_ci    if "sparse" in is_sparse:
875f9996aaSopenharmony_ci        tmp_device = "%s.tmp" % device
885f9996aaSopenharmony_ci        run_cmd(" ".join(["img2simg ", device, " ", tmp_device]))
895f9996aaSopenharmony_ci        os.rename(tmp_device, device)
905f9996aaSopenharmony_ci
915f9996aaSopenharmony_ci
925f9996aaSopenharmony_cidef mk_system_img(mkfs_tools: str, mk_configs: str, device: str, src_dir: str, is_sparse: str):
935f9996aaSopenharmony_ci    src_dir = build_rootdir(src_dir)
945f9996aaSopenharmony_ci    mk_configs = " ".join([src_dir, device, mk_configs])
955f9996aaSopenharmony_ci    res = run_cmd(" ".join([mkfs_tools, mk_configs]))
965f9996aaSopenharmony_ci    verify_ret(res)
975f9996aaSopenharmony_ci    sparse_img2simg(is_sparse, device)
985f9996aaSopenharmony_ci    if os.path.isdir(src_dir):
995f9996aaSopenharmony_ci        shutil.rmtree(src_dir)
1005f9996aaSopenharmony_ci
1015f9996aaSopenharmony_ci
1025f9996aaSopenharmony_cidef mk_ramdisk_img(mkfs_tools: str, mk_configs: str, device: str, src_dir: str, is_sparse: str):
1035f9996aaSopenharmony_ci    # get ramdisk sieze frome ramdisk_image_conf.txt
1045f9996aaSopenharmony_ci    ramdisk_size = mk_configs.split(" ")[1]
1055f9996aaSopenharmony_ci    mk_configs = \
1065f9996aaSopenharmony_ci            " ".join([src_dir, device, ramdisk_size])
1075f9996aaSopenharmony_ci    res = run_cmd(" ".join([mkfs_tools, mk_configs]))
1085f9996aaSopenharmony_ci    verify_ret(res)
1095f9996aaSopenharmony_ci
1105f9996aaSopenharmony_ci
1115f9996aaSopenharmony_cidef mk_other_img(mkfs_tools: str, mk_configs: str, device: str, src_dir: str, is_sparse: str):
1125f9996aaSopenharmony_ci    mk_configs = " ".join([src_dir, device, mk_configs])
1135f9996aaSopenharmony_ci    res = run_cmd(" ".join([mkfs_tools, mk_configs]))
1145f9996aaSopenharmony_ci    verify_ret(res)
1155f9996aaSopenharmony_ci    sparse_img2simg(is_sparse, device)
1165f9996aaSopenharmony_ci
1175f9996aaSopenharmony_ci
1185f9996aaSopenharmony_cidef mk_images(args):
1195f9996aaSopenharmony_ci    if len(args) != 4:
1205f9996aaSopenharmony_ci        print("mk_images need 4 args!!!")
1215f9996aaSopenharmony_ci        sys.exit(1)
1225f9996aaSopenharmony_ci    root_path = find_top()
1235f9996aaSopenharmony_ci    config_json = os.path.join(root_path, "out/ohos_config.json")
1245f9996aaSopenharmony_ci    config = {}
1255f9996aaSopenharmony_ci    with open(config_json, 'rb') as f:
1265f9996aaSopenharmony_ci        config = json.load(f)
1275f9996aaSopenharmony_ci    src_dir = args[0]
1285f9996aaSopenharmony_ci    config_file = args[1]
1295f9996aaSopenharmony_ci    device = args[2]
1305f9996aaSopenharmony_ci    is_sparse = args[3]
1315f9996aaSopenharmony_ci    mkfs_tools, mk_configs, _ = load_config(config_file)
1325f9996aaSopenharmony_ci    image_name = device.split("/")[-1]
1335f9996aaSopenharmony_ci    if image_name == "system.img":
1345f9996aaSopenharmony_ci        mk_system_img(mkfs_tools, mk_configs, device, src_dir, is_sparse)
1355f9996aaSopenharmony_ci    elif image_name == "ramdisk.img":
1365f9996aaSopenharmony_ci        mk_ramdisk_img(mkfs_tools, mk_configs, device, src_dir, is_sparse)
1375f9996aaSopenharmony_ci    elif image_name == "updater_ramdisk.img":
1385f9996aaSopenharmony_ci        if config.get('component_type', '') == 'system_component':
1395f9996aaSopenharmony_ci            return
1405f9996aaSopenharmony_ci        mk_ramdisk_img(mkfs_tools, mk_configs, device, src_dir, is_sparse)
1415f9996aaSopenharmony_ci    else:
1425f9996aaSopenharmony_ci        mk_other_img(mkfs_tools, mk_configs, device, src_dir, is_sparse)
1435f9996aaSopenharmony_ci
1445f9996aaSopenharmony_ci
1455f9996aaSopenharmony_ciif __name__ == '__main__':
1465f9996aaSopenharmony_ci    mk_images(sys.argv[1:])
147