Deploy script - set correct hashes with esptool
This commit is contained in:
parent
89bc990bec
commit
654ff2e7c3
|
@ -1,19 +1,14 @@
|
||||||
import struct
|
import struct
|
||||||
import locale
|
|
||||||
from collections import namedtuple
|
from collections import namedtuple
|
||||||
from datetime import datetime
|
from datetime import datetime
|
||||||
import subprocess
|
import subprocess
|
||||||
from distutils.version import StrictVersion
|
from distutils.version import StrictVersion
|
||||||
import subprocess
|
from esptool import LoadFirmwareImage # required to get hash and checksum right
|
||||||
import os
|
import os
|
||||||
|
|
||||||
#locale.setlocale(locale.LC_ALL, 'en_US')
|
# locale.setlocale(locale.LC_ALL, 'en_US')
|
||||||
|
|
||||||
# sizeof(esp_image_header_t) + sizeof(esp_image_segment_header_t)
|
APP_DESC_SIZE = 256 # sizeof(esp_app_desc_t)
|
||||||
APP_DESC_OFFSET = 32
|
|
||||||
|
|
||||||
# sizeof(esp_app_desc_t)
|
|
||||||
APP_DESC_SIZE = 256
|
|
||||||
|
|
||||||
APP_DESC_STRUCT = "<II2I32s32s16s16s32s32B20I"
|
APP_DESC_STRUCT = "<II2I32s32s16s16s32s32B20I"
|
||||||
AppDesc = namedtuple('AppDesc',
|
AppDesc = namedtuple('AppDesc',
|
||||||
|
@ -28,6 +23,7 @@ AppDesc = namedtuple('AppDesc',
|
||||||
]
|
]
|
||||||
)
|
)
|
||||||
|
|
||||||
|
|
||||||
def version_number_from_git(tag_prefix='release/', sha_length=10, version_format="{version}.dev{commits}+{sha}"):
|
def version_number_from_git(tag_prefix='release/', sha_length=10, version_format="{version}.dev{commits}+{sha}"):
|
||||||
def get_released_versions():
|
def get_released_versions():
|
||||||
tags = sorted(subprocess.getoutput('git tag').split('\n'))
|
tags = sorted(subprocess.getoutput('git tag').split('\n'))
|
||||||
|
@ -64,24 +60,22 @@ def version_number_from_git(tag_prefix='release/', sha_length=10, version_format
|
||||||
return version_string
|
return version_string
|
||||||
|
|
||||||
|
|
||||||
def read_app_description(file_name):
|
def read_app_description_from_segment(segment):
|
||||||
def process_bytes(b):
|
def process_bytes(b):
|
||||||
if not isinstance(b, bytes):
|
if not isinstance(b, bytes):
|
||||||
return b
|
return b
|
||||||
s = b.decode()
|
s = b.decode()
|
||||||
return s[:s.find("\x00")]
|
return s[:s.find("\x00")]
|
||||||
|
|
||||||
with open(file_name, 'rb') as f:
|
unpacked = struct.unpack(APP_DESC_STRUCT, segment.data[:APP_DESC_SIZE])
|
||||||
f.seek(APP_DESC_OFFSET, 0)
|
unpacked = tuple(process_bytes(e) for e in unpacked)
|
||||||
raw_app_desc = f.read(APP_DESC_SIZE)
|
magic_word, secure_version, _, _, version, project_name, time, date, idf_ver, app_elf_sha256, *_ = unpacked
|
||||||
unpacked = struct.unpack(APP_DESC_STRUCT, raw_app_desc)
|
assert magic_word == 0xABCD5432
|
||||||
unpacked = tuple(process_bytes(e) for e in unpacked)
|
return AppDesc(secure_version, version, project_name, time, date, idf_ver, app_elf_sha256)
|
||||||
magic_word, secure_version, _, _, version, project_name, time, date, idf_ver, app_elf_sha256, *_ = unpacked
|
|
||||||
assert magic_word == 0xABCD5432
|
|
||||||
return AppDesc(secure_version, version, project_name, time, date, idf_ver, app_elf_sha256)
|
|
||||||
|
|
||||||
|
|
||||||
def patch_app_description(file_name, version, project_name, time, date):
|
|
||||||
|
def patch_app_description_in_segment(segment, version, project_name, time, date):
|
||||||
assert len(version) < 32
|
assert len(version) < 32
|
||||||
assert len(project_name) < 32
|
assert len(project_name) < 32
|
||||||
assert len(time) < 16
|
assert len(time) < 16
|
||||||
|
@ -93,39 +87,41 @@ def patch_app_description(file_name, version, project_name, time, date):
|
||||||
assert len(s) == total_length
|
assert len(s) == total_length
|
||||||
return s
|
return s
|
||||||
|
|
||||||
with open(file_name, 'r+b') as f:
|
raw_app_desc = segment.data[:APP_DESC_SIZE]
|
||||||
f.seek(APP_DESC_OFFSET, 0)
|
unpacked = list(struct.unpack(APP_DESC_STRUCT, raw_app_desc))
|
||||||
raw_app_desc = f.read(APP_DESC_SIZE)
|
unpacked[4] = fill_zeros(version, 32)
|
||||||
unpacked = list(struct.unpack(APP_DESC_STRUCT, raw_app_desc))
|
unpacked[5] = fill_zeros(project_name, 32)
|
||||||
unpacked[4] = fill_zeros(version, 32)
|
unpacked[6] = fill_zeros(time, 16)
|
||||||
unpacked[5] = fill_zeros(project_name, 32)
|
unpacked[7] = fill_zeros(date, 16)
|
||||||
unpacked[6] = fill_zeros(time, 16)
|
packed = struct.pack(APP_DESC_STRUCT, *unpacked)
|
||||||
unpacked[7] = fill_zeros(date, 16)
|
|
||||||
packed = struct.pack(APP_DESC_STRUCT, *unpacked)
|
original_data = segment.data
|
||||||
f.seek(APP_DESC_OFFSET, 0)
|
segment.data = packed + original_data[APP_DESC_SIZE:]
|
||||||
f.write(packed)
|
|
||||||
|
|
||||||
|
|
||||||
def add_info_to_firmware(firmware_file, version):
|
def patch_firmware(input_file, output_file):
|
||||||
|
img = LoadFirmwareImage("esp32", input_file)
|
||||||
|
version = version_number_from_git()
|
||||||
|
|
||||||
now = datetime.now()
|
now = datetime.now()
|
||||||
date = now.strftime("%b %d %Y")
|
|
||||||
time = now.strftime("%H:%M:%S")
|
time = now.strftime("%H:%M:%S")
|
||||||
patch_app_description(firmware_file, version=version,
|
date = now.strftime("%b %d %Y")
|
||||||
project_name="swimtracker.bauer.tech", time=time, date=date)
|
patch_app_description_in_segment(img.segments[0], version, "swimtracker.bauer.tech", time, date)
|
||||||
|
img.save(output_file)
|
||||||
|
|
||||||
|
|
||||||
if __name__ == "__main__":
|
if __name__ == "__main__":
|
||||||
firmware_file = ".pio/build/esp32/firmware.bin"
|
firmware_file = ".pio/build/esp32/firmware.bin"
|
||||||
version_file_name = "VERSION"
|
version_file_name = "VERSION"
|
||||||
|
|
||||||
version = version_number_from_git()
|
patch_firmware(firmware_file, firmware_file) # patch inplace
|
||||||
add_info_to_firmware(firmware_file, version)
|
|
||||||
print(read_app_description(firmware_file))
|
|
||||||
with open(version_file_name, "w") as version_file:
|
with open(version_file_name, "w") as version_file:
|
||||||
print(version, file=version_file)
|
print(version_number_from_git(), file=version_file)
|
||||||
|
|
||||||
subprocess.run(["scp", firmware_file, "root@server:/volumes/swimtracker-update"])
|
subprocess.run(["scp", firmware_file, "root@server:/volumes/swimtracker-update"])
|
||||||
subprocess.run(["scp", version_file_name, "root@server:/volumes/swimtracker-update"])
|
subprocess.run(["scp", version_file_name, "root@server:/volumes/swimtracker-update"])
|
||||||
|
|
||||||
os.unlink(firmware_file)
|
os.unlink(firmware_file)
|
||||||
os.unlink(version_file_name)
|
os.unlink(version_file_name)
|
||||||
|
|
||||||
|
|
Loading…
Reference in New Issue