118 lines
3.7 KiB
Python
118 lines
3.7 KiB
Python
#!/usr/bin/python3
|
|
# -*- coding: utf-8 -*-
|
|
from zipfile import ZipFile, ZIP_DEFLATED
|
|
from XmlParser import XmlParser
|
|
from hashlib import md5
|
|
from os import path
|
|
from tempfile import NamedTemporaryFile
|
|
import logging
|
|
import argparse
|
|
from raw2cimg import ImagerBuilder
|
|
|
|
FORMAT = "%(levelname)s: %(message)s"
|
|
logging.basicConfig(level=logging.INFO, format=FORMAT)
|
|
|
|
|
|
def argparser():
|
|
parser = argparse.ArgumentParser(description="Pack CVI upgrade package")
|
|
parser.add_argument("xml", help="path to partition xml")
|
|
parser.add_argument("input", metavar="image_folder", help="path to images folder")
|
|
parser.add_argument(
|
|
"-v", "--verbose", help="increase output verbosity", action="store_true"
|
|
)
|
|
parser.add_argument(
|
|
"-o",
|
|
"--output",
|
|
help="path to output file, default is upgrade.zip",
|
|
default="upgrade.zip",
|
|
)
|
|
parser.add_argument(
|
|
"-f",
|
|
"--file",
|
|
nargs=2,
|
|
metavar=("FOLDER IN ZIP", "FILE"),
|
|
help="extra files you want to add to the upgrade.zip, "
|
|
"all the files will add to utils folder.",
|
|
action="append",
|
|
)
|
|
args = parser.parse_args()
|
|
if args.verbose:
|
|
logging.debug("Enable more verbose output")
|
|
logging.getLogger().setLevel(level=logging.DEBUG)
|
|
|
|
return args
|
|
|
|
|
|
def getMD5Sum(file_path: str) -> str:
|
|
m = md5()
|
|
# Partially caculate md5sum for speeding up
|
|
with open(file_path, "rb") as f:
|
|
for chunk in iter(lambda: f.read(4096), b""):
|
|
m.update(chunk)
|
|
|
|
return m.hexdigest()
|
|
|
|
|
|
def main():
|
|
args = argparser()
|
|
parser = XmlParser(args.xml)
|
|
parts = parser.parse(install=args.input)
|
|
storage = parser.getStorage()
|
|
logging.debug(args)
|
|
|
|
imgBuilder = ImagerBuilder(storage, args.input)
|
|
# create a ZipFile object
|
|
with ZipFile(args.output, "w", ZIP_DEFLATED) as zipObj:
|
|
# create metadata for record md5sum
|
|
metadata = NamedTemporaryFile(prefix="meta")
|
|
|
|
# Since emmc will not define fip in partition.xml add them
|
|
# manually.
|
|
if storage == "emmc":
|
|
fip_path = path.join(args.input, "fip.bin")
|
|
if path.isfile(fip_path):
|
|
zipObj.write(fip_path, "fip.bin")
|
|
|
|
# Add partition file to zip
|
|
for p in parts:
|
|
# Skip file size is equal to zero(Not exists)
|
|
if p["file_size"] == 0:
|
|
continue
|
|
# Try pack header first to avoid user copy image without header
|
|
if p["file_name"] != "fip.bin":
|
|
imgBuilder.packHeader(p)
|
|
|
|
# Add file to zipfile
|
|
zipObj.write(p["file_path"], path.basename(p["file_path"]))
|
|
|
|
# get MD5sum
|
|
m = getMD5Sum(p["file_path"])
|
|
logging.debug("%s %s" % (path.basename(p["file_path"]), m))
|
|
with open(metadata.name, "a") as meta:
|
|
meta.write("%s %s\n" % (m, path.basename(p["file_path"])))
|
|
|
|
# Add extra files to zip
|
|
if args.file:
|
|
for folder, f in args.file:
|
|
logging.debug(f)
|
|
m = getMD5Sum(f)
|
|
in_zip_path = path.join(folder, path.basename(f))
|
|
logging.debug("%s %s\n" % (m, in_zip_path))
|
|
with open(metadata.name, "a") as meta:
|
|
meta.write("%s %s\n" % (m, in_zip_path))
|
|
zipObj.write(f, in_zip_path)
|
|
|
|
# Add metadata.txt and partition.xml
|
|
zipObj.write(metadata.name, path.join("META", "metadata.txt"))
|
|
zipObj.write(args.xml, path.basename(args.xml))
|
|
# Show zipinfo message
|
|
if args.verbose:
|
|
for info in zipObj.infolist():
|
|
logging.debug(info)
|
|
logging.info("Packing %s done!" % args.output)
|
|
return
|
|
|
|
|
|
if __name__ == "__main__":
|
|
main()
|