use f-strings and test with 3.9

This commit is contained in:
Fabian Kaczmarczyck
2021-09-17 12:06:45 +02:00
committed by kaczmarczyck
parent 18ba4368e4
commit 31df2ca45e
3 changed files with 63 additions and 84 deletions

View File

@@ -12,7 +12,7 @@ jobs:
runs-on: ubuntu-18.04 runs-on: ubuntu-18.04
strategy: strategy:
matrix: matrix:
python-version: [3.6, 3.7, 3.8] python-version: [3.6, 3.7, 3.8, 3.9]
steps: steps:
- uses: actions/checkout@v2 - uses: actions/checkout@v2
- name: Set up Python ${{ matrix.python-version }} - name: Set up Python ${{ matrix.python-version }}

119
deploy.py
View File

@@ -177,39 +177,32 @@ def get_supported_boards():
def fatal(msg): def fatal(msg):
print("{style_begin}fatal:{style_end} {message}".format( print(f"{colorama.Fore.RED + colorama.Style.BRIGHT}fatal:"
style_begin=colorama.Fore.RED + colorama.Style.BRIGHT, f"{colorama.Style.RESET_ALL} {msg}")
style_end=colorama.Style.RESET_ALL,
message=msg))
sys.exit(1) sys.exit(1)
def error(msg): def error(msg):
print("{style_begin}error:{style_end} {message}".format( print(f"{colorama.Fore.RED}error:{colorama.Style.RESET_ALL} {msg}")
style_begin=colorama.Fore.RED,
style_end=colorama.Style.RESET_ALL,
message=msg))
def info(msg): def info(msg):
print("{style_begin}info:{style_end} {message}".format( print(f"{colorama.Fore.GREEN + colorama.Style.BRIGHT}info:"
style_begin=colorama.Fore.GREEN + colorama.Style.BRIGHT, f"{colorama.Style.RESET_ALL} {msg}")
style_end=colorama.Style.RESET_ALL,
message=msg))
def assert_mandatory_binary(binary): def assert_mandatory_binary(binary):
if not shutil.which(binary): if not shutil.which(binary):
fatal(("Couldn't find {} binary. Make sure it is installed and " fatal((f"Couldn't find {binary} binary. Make sure it is installed and "
"that your PATH is set correctly.").format(binary)) "that your PATH is set correctly."))
def assert_python_library(module): def assert_python_library(module):
try: try:
__import__(module) __import__(module)
except ModuleNotFoundError: except ModuleNotFoundError:
fatal(("Couldn't load python3 module {name}. " fatal((f"Couldn't load python3 module {module}. "
"Try to run: pip3 install {name}").format(name=module)) f"Try to run: pip3 install {module}"))
class RemoveConstAction(argparse.Action): class RemoveConstAction(argparse.Action):
@@ -284,7 +277,7 @@ class OpenSKInstaller:
subprocess.run( subprocess.run(
cmd, stdout=stdout, timeout=None, check=True, env=env, cwd=cwd) cmd, stdout=stdout, timeout=None, check=True, env=env, cwd=cwd)
except subprocess.CalledProcessError as e: except subprocess.CalledProcessError as e:
fatal("Failed to execute {}: {}".format(cmd[0], str(e))) fatal(f"Failed to execute {cmd[0]}: {str(e)}")
def checked_command_output(self, cmd, env=None, cwd=None): def checked_command_output(self, cmd, env=None, cwd=None):
cmd_output = "" cmd_output = ""
@@ -297,7 +290,7 @@ class OpenSKInstaller:
env=env, env=env,
cwd=cwd).stdout cwd=cwd).stdout
except subprocess.CalledProcessError as e: except subprocess.CalledProcessError as e:
fatal("Failed to execute {}: {}".format(cmd[0], str(e))) fatal(f"Failed to execute {cmd[0]}: {str(e)}")
# Unreachable because fatal() will exit # Unreachable because fatal() will exit
return cmd_output.decode() return cmd_output.decode()
@@ -324,7 +317,7 @@ class OpenSKInstaller:
current_version = self.checked_command_output(["rustc", "--version"]) current_version = self.checked_command_output(["rustc", "--version"])
if not (target_toolchain[0] in current_version and if not (target_toolchain[0] in current_version and
target_toolchain[1] in current_version): target_toolchain[1] in current_version):
info("Updating rust toolchain to {}".format("-".join(target_toolchain))) info(f"Updating rust toolchain to {'-'.join(target_toolchain)}")
# Need to update # Need to update
rustup_install = ["rustup"] rustup_install = ["rustup"]
if self.args.verbose_build: if self.args.verbose_build:
@@ -341,7 +334,7 @@ class OpenSKInstaller:
info("Rust toolchain up-to-date") info("Rust toolchain up-to-date")
def build_tockos(self): def build_tockos(self):
info("Building Tock OS for board {}".format(self.args.board)) info(f"Building Tock OS for board {self.args.board}")
props = SUPPORTED_BOARDS[self.args.board] props = SUPPORTED_BOARDS[self.args.board]
out_directory = os.path.join("third_party", "tock", "target", props.arch, out_directory = os.path.join("third_party", "tock", "target", props.arch,
"release") "release")
@@ -353,7 +346,7 @@ class OpenSKInstaller:
self.checked_command(["make"], cwd=props.path, env=env) self.checked_command(["make"], cwd=props.path, env=env)
def build_example(self): def build_example(self):
info("Building example {}".format(self.args.application)) info(f"Building example {self.args.application}")
self._build_app_or_example(is_example=True) self._build_app_or_example(is_example=True)
def build_opensk(self): def build_opensk(self):
@@ -370,12 +363,12 @@ class OpenSKInstaller:
props = SUPPORTED_BOARDS[self.args.board] props = SUPPORTED_BOARDS[self.args.board]
rust_flags = [ rust_flags = [
"-C", "-C",
"link-arg=-T{}".format(props.app_ldscript), f"link-arg=-T{props.app_ldscript}",
"-C", "-C",
"relocation-model=static", "relocation-model=static",
"-D", "-D",
"warnings", "warnings",
"--remap-path-prefix={}=".format(os.getcwd()), f"--remap-path-prefix={os.getcwd()}=",
"-C", "-C",
"link-arg=-icf=all", "link-arg=-icf=all",
"-C", "-C",
@@ -386,8 +379,8 @@ class OpenSKInstaller:
env["APP_HEAP_SIZE"] = str(APP_HEAP_SIZE) env["APP_HEAP_SIZE"] = str(APP_HEAP_SIZE)
command = [ command = [
"cargo", "build", "--release", "--target={}".format(props.arch), "cargo", "build", "--release", f"--target={props.arch}",
"--features={}".format(",".join(self.args.features)) f"--features={','.join(self.args.features)}"
] ]
if is_example: if is_example:
command.extend(["--example", self.args.application]) command.extend(["--example", self.args.application])
@@ -418,18 +411,16 @@ class OpenSKInstaller:
def create_tab_file(self, binaries): def create_tab_file(self, binaries):
assert binaries assert binaries
assert self.args.application assert self.args.application
info("Generating Tock TAB file for application/example {}".format( info("Generating Tock TAB file for application/example "
self.args.application)) f"{self.args.application}")
elf2tab_ver = self.checked_command_output( elf2tab_ver = self.checked_command_output(
["elf2tab/bin/elf2tab", "--version"]).split( ["elf2tab/bin/elf2tab", "--version"]).split(
"\n", maxsplit=1)[0] "\n", maxsplit=1)[0]
if elf2tab_ver != "elf2tab 0.7.0": if elf2tab_ver != "elf2tab 0.7.0":
error( error(("Detected unsupported elf2tab version {elf2tab_ver!a}. The "
("Detected unsupported elf2tab version {!a}. The following " "following commands may fail. Please use 0.7.0 instead."))
"commands may fail. Please use 0.7.0 instead.").format(elf2tab_ver))
os.makedirs(self.tab_folder, exist_ok=True) os.makedirs(self.tab_folder, exist_ok=True)
tab_filename = os.path.join(self.tab_folder, tab_filename = os.path.join(self.tab_folder, f"{self.args.application}.tab")
"{}.tab".format(self.args.application))
elf2tab_args = [ elf2tab_args = [
"elf2tab/bin/elf2tab", "--deterministic", "--package-name", "elf2tab/bin/elf2tab", "--deterministic", "--package-name",
self.args.application, "-o", tab_filename self.args.application, "-o", tab_filename
@@ -438,7 +429,7 @@ class OpenSKInstaller:
elf2tab_args.append("--verbose") elf2tab_args.append("--verbose")
stack_sizes = set() stack_sizes = set()
for arch, app_file in binaries.items(): for arch, app_file in binaries.items():
dest_file = os.path.join(self.tab_folder, "{}.elf".format(arch)) dest_file = os.path.join(self.tab_folder, f"{arch}.elf")
shutil.copyfile(app_file, dest_file) shutil.copyfile(app_file, dest_file)
elf2tab_args.append(dest_file) elf2tab_args.append(dest_file)
# extract required stack size directly from binary # extract required stack size directly from binary
@@ -452,9 +443,8 @@ class OpenSKInstaller:
error("Detected different stack sizes across tab files.") error("Detected different stack sizes across tab files.")
elf2tab_args.extend([ elf2tab_args.extend([
"--stack={}".format(stack_sizes.pop()), f"--stack={stack_sizes.pop()}", f"--app-heap={APP_HEAP_SIZE}",
"--app-heap={}".format(APP_HEAP_SIZE), "--kernel-heap=1024", "--kernel-heap=1024", "--protected-region-size=64"
"--protected-region-size=64"
]) ])
if self.args.elf2tab_output: if self.args.elf2tab_output:
output = self.checked_command_output(elf2tab_args) output = self.checked_command_output(elf2tab_args)
@@ -464,7 +454,7 @@ class OpenSKInstaller:
def install_tab_file(self, tab_filename): def install_tab_file(self, tab_filename):
assert self.args.application assert self.args.application
info("Installing Tock application {}".format(self.args.application)) info(f"Installing Tock application {self.args.application}")
board_props = SUPPORTED_BOARDS[self.args.board] board_props = SUPPORTED_BOARDS[self.args.board]
args = copy.copy(self.tockloader_default_args) args = copy.copy(self.tockloader_default_args)
setattr(args, "app_address", board_props.app_address) setattr(args, "app_address", board_props.app_address)
@@ -477,8 +467,8 @@ class OpenSKInstaller:
try: try:
tock.install(tabs, replace="yes", erase=args.erase) tock.install(tabs, replace="yes", erase=args.erase)
except TockLoaderException as e: except TockLoaderException as e:
fatal("Couldn't install Tock application {}: {}".format( fatal("Couldn't install Tock application "
self.args.application, str(e))) f"{self.args.application}: {str(e)}")
def get_padding(self): def get_padding(self):
padding = tbfh.TBFHeaderPadding( padding = tbfh.TBFHeaderPadding(
@@ -490,8 +480,8 @@ class OpenSKInstaller:
board_props = SUPPORTED_BOARDS[self.args.board] board_props = SUPPORTED_BOARDS[self.args.board]
kernel_file = os.path.join("third_party", "tock", "target", kernel_file = os.path.join("third_party", "tock", "target",
board_props.arch, "release", board_props.arch, "release",
"{}.bin".format(self.args.board)) f"{self.args.board}.bin")
info("Flashing file {}.".format(kernel_file)) info(f"Flashing file {kernel_file}.")
with open(kernel_file, "rb") as f: with open(kernel_file, "rb") as f:
kernel = f.read() kernel = f.read()
args = copy.copy(self.tockloader_default_args) args = copy.copy(self.tockloader_default_args)
@@ -501,7 +491,7 @@ class OpenSKInstaller:
try: try:
tock.flash_binary(kernel, board_props.kernel_address) tock.flash_binary(kernel, board_props.kernel_address)
except TockLoaderException as e: except TockLoaderException as e:
fatal("Couldn't install Tock OS: {}".format(str(e))) fatal(f"Couldn't install Tock OS: {str(e)}")
def install_padding(self): def install_padding(self):
padding = self.get_padding() padding = self.get_padding()
@@ -514,7 +504,7 @@ class OpenSKInstaller:
try: try:
tock.flash_binary(padding, args.address) tock.flash_binary(padding, args.address)
except TockLoaderException as e: except TockLoaderException as e:
fatal("Couldn't install padding: {}".format(str(e))) fatal(f"Couldn't install padding: {str(e)}")
def clear_apps(self): def clear_apps(self):
args = copy.copy(self.tockloader_default_args) args = copy.copy(self.tockloader_default_args)
@@ -530,8 +520,7 @@ class OpenSKInstaller:
tock.erase_apps() tock.erase_apps()
except TockLoaderException as e: except TockLoaderException as e:
# Erasing apps is not critical # Erasing apps is not critical
info(("A non-critical error occurred while erasing " info(f"A non-critical error occurred while erasing apps: {str(e)}")
"apps: {}".format(str(e))))
def clear_storage(self): def clear_storage(self):
if self.args.programmer == "none": if self.args.programmer == "none":
@@ -546,16 +535,15 @@ class OpenSKInstaller:
try: try:
tock.flash_binary(storage, board_props.storage_address) tock.flash_binary(storage, board_props.storage_address)
except TockLoaderException as e: except TockLoaderException as e:
fatal("Couldn't erase the persistent storage: {}".format(str(e))) fatal(f"Couldn't erase the persistent storage: {str(e)}")
return 0 return 0
if self.args.programmer == "pyocd": if self.args.programmer == "pyocd":
self.checked_command([ self.checked_command([
"pyocd", "erase", "--target={}".format(board_props.pyocd_target), "pyocd", "erase", f"--target={board_props.pyocd_target}", "--sector",
"--sector", "{}+{}".format(board_props.storage_address, f"{board_props.storage_address}+{board_props.storage_size}"
board_props.storage_size)
]) ])
return 0 return 0
fatal("Programmer {} is not supported.".format(self.args.programmer)) fatal(f"Programmer {self.args.programmer} is not supported.")
# pylint: disable=protected-access # pylint: disable=protected-access
def verify_flashed_app(self, expected_app): def verify_flashed_app(self, expected_app):
@@ -582,7 +570,7 @@ class OpenSKInstaller:
# Process kernel # Process kernel
kernel_path = os.path.join("third_party", "tock", "target", kernel_path = os.path.join("third_party", "tock", "target",
board_props.arch, "release", board_props.arch, "release",
"{}.bin".format(self.args.board)) f"{self.args.board}.bin")
with open(kernel_path, "rb") as kernel: with open(kernel_path, "rb") as kernel:
kern_hex = intelhex.IntelHex() kern_hex = intelhex.IntelHex()
kern_hex.frombytes(kernel.read(), offset=board_props.kernel_address) kern_hex.frombytes(kernel.read(), offset=board_props.kernel_address)
@@ -597,25 +585,25 @@ class OpenSKInstaller:
final_hex.merge(padding_hex, overlap="error") final_hex.merge(padding_hex, overlap="error")
# Now we can add the application from the TAB file # Now we can add the application from the TAB file
app_tab_path = "target/tab/{}.tab".format(self.args.application) app_tab_path = f"target/tab/{self.args.application}.tab"
assert os.path.exists(app_tab_path) assert os.path.exists(app_tab_path)
app_tab = tab.TAB(app_tab_path) app_tab = tab.TAB(app_tab_path)
if board_props.arch not in app_tab.get_supported_architectures(): if board_props.arch not in app_tab.get_supported_architectures():
fatal(("It seems that the TAB file was not produced for the " fatal(("It seems that the TAB file was not produced for the "
"architecture {}".format(board_props.arch))) "architecture {board_props.arch}"))
app_hex = intelhex.IntelHex() app_hex = intelhex.IntelHex()
app_hex.frombytes( app_hex.frombytes(
app_tab.extract_app(board_props.arch).get_binary( app_tab.extract_app(board_props.arch).get_binary(
board_props.app_address), board_props.app_address),
offset=board_props.app_address) offset=board_props.app_address)
final_hex.merge(app_hex) final_hex.merge(app_hex)
info("Generating all-merged HEX file: {}".format(dest_file)) info(f"Generating all-merged HEX file: {dest_file}")
final_hex.tofile(dest_file, format="hex") final_hex.tofile(dest_file, format="hex")
def check_prerequisites(self): def check_prerequisites(self):
if not tockloader.__version__.startswith("1.5."): if not tockloader.__version__.startswith("1.5."):
fatal(("Your version of tockloader seems incompatible: found {}, " fatal(("Your version of tockloader seems incompatible: found "
"expected 1.5.x.".format(tockloader.__version__))) f"{tockloader.__version__}, expected 1.5.x."))
if self.args.programmer == "jlink": if self.args.programmer == "jlink":
assert_mandatory_binary("JLinkExe") assert_mandatory_binary("JLinkExe")
@@ -636,7 +624,7 @@ class OpenSKInstaller:
nrfutil_version = __import__("nordicsemi.version").version.NRFUTIL_VERSION nrfutil_version = __import__("nordicsemi.version").version.NRFUTIL_VERSION
if not nrfutil_version.startswith("6."): if not nrfutil_version.startswith("6."):
fatal(("You need to install nrfutil python3 package v6.0 or above. " fatal(("You need to install nrfutil python3 package v6.0 or above. "
"Found: {}".format(nrfutil_version))) "Found: {nrfutil_version}"))
if not SUPPORTED_BOARDS[self.args.board].nordic_dfu: if not SUPPORTED_BOARDS[self.args.board].nordic_dfu:
fatal("This board doesn't support flashing over DFU.") fatal("This board doesn't support flashing over DFU.")
@@ -680,7 +668,7 @@ class OpenSKInstaller:
# Install padding and application if needed # Install padding and application if needed
if self.args.application: if self.args.application:
self.install_padding() self.install_padding()
self.install_tab_file("target/tab/{}.tab".format(self.args.application)) self.install_tab_file(f"target/tab/{self.args.application}.tab")
if self.verify_flashed_app(self.args.application): if self.verify_flashed_app(self.args.application):
info("You're all set!") info("You're all set!")
return 0 return 0
@@ -692,22 +680,22 @@ class OpenSKInstaller:
return 0 return 0
if self.args.programmer in ("pyocd", "nordicdfu", "none"): if self.args.programmer in ("pyocd", "nordicdfu", "none"):
dest_file = "target/{}_merged.hex".format(self.args.board) dest_file = f"target/{self.args.board}_merged.hex"
os.makedirs("target", exist_ok=True) os.makedirs("target", exist_ok=True)
self.create_hex_file(dest_file) self.create_hex_file(dest_file)
if self.args.programmer == "pyocd": if self.args.programmer == "pyocd":
info("Flashing HEX file") info("Flashing HEX file")
self.checked_command([ self.checked_command([
"pyocd", "flash", "--target={}".format(board_props.pyocd_target), "pyocd", "flash", f"--target={board_props.pyocd_target}",
"--format=hex", "--erase=auto", dest_file "--format=hex", "--erase=auto", dest_file
]) ])
if self.args.programmer == "nordicdfu": if self.args.programmer == "nordicdfu":
info("Creating DFU package") info("Creating DFU package")
dfu_pkg_file = "target/{}_dfu.zip".format(self.args.board) dfu_pkg_file = f"target/{self.args.board}_dfu.zip"
self.checked_command([ self.checked_command([
"nrfutil", "pkg", "generate", "--hw-version=52", "--sd-req=0", "nrfutil", "pkg", "generate", "--hw-version=52", "--sd-req=0",
"--application-version=1", "--application={}".format(dest_file), "--application-version=1", f"--application={dest_file}",
dfu_pkg_file dfu_pkg_file
]) ])
info( info(
@@ -730,9 +718,8 @@ class OpenSKInstaller:
info("Flashing device using DFU...") info("Flashing device using DFU...")
return subprocess.run( return subprocess.run(
[ [
"nrfutil", "dfu", "usb-serial", "nrfutil", "dfu", "usb-serial", f"--package={dfu_pkg_file}",
"--package={}".format(dfu_pkg_file), f"--serial-number={serial_number[0]}"
"--serial-number={}".format(serial_number[0])
], ],
check=False, check=False,
timeout=None, timeout=None,
@@ -772,7 +759,7 @@ def main(args):
if args.listing: if args.listing:
# Missing check? # Missing check?
fatal("Listing {} is not implemented.".format(args.listing)) fatal(f"Listing {args.listing} is not implemented.")
OpenSKInstaller(args).run() OpenSKInstaller(args).run()

View File

@@ -40,25 +40,18 @@ OPENSK_VENDOR_CONFIGURE = 0x40
def fatal(msg): def fatal(msg):
tqdm.write("{style_begin}fatal:{style_end} {message}".format( tqdm.write(f"{colorama.Fore.RED + colorama.Style.BRIGHT}fatal:"
style_begin=colorama.Fore.RED + colorama.Style.BRIGHT, f"{colorama.Style.RESET_ALL} {msg}")
style_end=colorama.Style.RESET_ALL,
message=msg))
sys.exit(1) sys.exit(1)
def error(msg): def error(msg):
tqdm.write("{style_begin}error:{style_end} {message}".format( tqdm.write(f"{colorama.Fore.RED}error:{colorama.Style.RESET_ALL} {msg}")
style_begin=colorama.Fore.RED,
style_end=colorama.Style.RESET_ALL,
message=msg))
def info(msg): def info(msg):
tqdm.write("{style_begin}info:{style_end} {message}".format( tqdm.write(f"{colorama.Fore.GREEN + colorama.Style.BRIGHT}info:"
style_begin=colorama.Fore.GREEN + colorama.Style.BRIGHT, f"{colorama.Style.RESET_ALL} {msg}")
style_end=colorama.Style.RESET_ALL,
message=msg))
def get_opensk_devices(batch_mode): def get_opensk_devices(batch_mode):
@@ -137,16 +130,15 @@ def main(args):
if authenticator.device.capabilities & hid.CAPABILITY.WINK: if authenticator.device.capabilities & hid.CAPABILITY.WINK:
authenticator.device.wink() authenticator.device.wink()
aaguid = uuid.UUID(bytes=authenticator.get_info().aaguid) aaguid = uuid.UUID(bytes=authenticator.get_info().aaguid)
info("Programming OpenSK device AAGUID {} ({}).".format( info(f"Programming OpenSK device AAGUID {aaguid} ({authenticator.device}).")
aaguid, authenticator.device))
info("Please touch the device to confirm...") info("Please touch the device to confirm...")
try: try:
result = authenticator.send_cbor( result = authenticator.send_cbor(
OPENSK_VENDOR_CONFIGURE, OPENSK_VENDOR_CONFIGURE,
data=cbor_data, data=cbor_data,
) )
info("Certificate: {}".format("Present" if result[1] else "Missing")) info(f"Certificate: {'Present' if result[1] else 'Missing'}")
info("Private Key: {}".format("Present" if result[2] else "Missing")) info(f"Private Key: {'Present' if result[2] else 'Missing'}")
if args.lock: if args.lock:
info("Device is now locked down!") info("Device is now locked down!")
except ctap.CtapError as ex: except ctap.CtapError as ex:
@@ -160,7 +152,7 @@ def main(args):
("Failed to configure OpenSK (device is partially programmed but " ("Failed to configure OpenSK (device is partially programmed but "
"the given cert/key don't match the ones currently programmed).")) "the given cert/key don't match the ones currently programmed)."))
else: else:
error("Failed to configure OpenSK (unknown error: {}".format(ex)) error(f"Failed to configure OpenSK (unknown error: {ex}")
if __name__ == "__main__": if __name__ == "__main__":