From f96f52e0834870afae1589a5ee6dc5e1f46a8ede Mon Sep 17 00:00:00 2001 From: Jean-Pierre De Jesus DIAZ Date: Mon, 23 Oct 2023 15:52:58 +0200 Subject: [PATCH] SFT-2917: Allow using Docker with sudo. Signed-off-by: Jean-Pierre De Jesus DIAZ --- .gitignore | 2 ++ Dockerfile | 19 ++++++++++ Justfile | 100 +++++++++++++++++++++++++++++++---------------------- run.sh | 44 +++++++++++++++++++++++ 4 files changed, 123 insertions(+), 42 deletions(-) create mode 100755 run.sh diff --git a/.gitignore b/.gitignore index b79c1e9c5..aa0ed4cff 100644 --- a/.gitignore +++ b/.gitignore @@ -99,3 +99,5 @@ simulator/snapshots/ *.gif *.pem .vscode + +.env diff --git a/Dockerfile b/Dockerfile index f73b07c33..6811c7f7c 100644 --- a/Dockerfile +++ b/Dockerfile @@ -53,3 +53,22 @@ RUN cargo install cbindgen@^0.24 && \ # Allow all users to use CARGO_HOME and RUSTUP_HOME. RUN chmod -R 777 /cargo && \ chmod -R 777 /rustup + +# Due to library differences between the host and container mpy-cross +# needs to be built for Docker using this image. +# +# This environment variable tells the MicroPython build system +# to use this mpy-cross binary. +ENV MPY_CROSS=/workspace/mpy-cross/mpy-cross-docker + +# Append cosign to the PATH environment variable. +ENV PATH=${PATH}:/workspace/ports/stm32/boards/Passport/tools/cosign/x86/release + +# Prevent from nesting docker. +ENV IN_DOCKER=true + +# User of the container must add /workspace volume pointing to the +# repository root. +WORKDIR /workspace + +ENTRYPOINT ["bash", "-c"] diff --git a/Justfile b/Justfile index 791b57354..84844f11c 100644 --- a/Justfile +++ b/Justfile @@ -3,61 +3,75 @@ # # Justfile - Root-level Justfile for Passport -export DOCKER_IMAGE := env_var_or_default('DOCKER_IMAGE', 'foundation-devices/passport2:latest') +export DOCKER_IMAGE := env_var_or_default("DOCKER_IMAGE", "foundation-devices/passport2:latest") + +set dotenv-load # Build the docker image build-docker: docker build -t ${DOCKER_IMAGE} . -# Build the firmware inside docker. -build-firmware screen="mono": mpy-cross (run-in-docker ("just ports/stm32/build " + screen)) +# Build the firmware. +build-firmware screen="mono": + ./run.sh just ports/stm32/build {{screen}} # build the bootloader inside docker -build-bootloader screen="mono": (run-in-docker ("just ports/stm32/boards/Passport/bootloader/build " + screen)) +build-bootloader screen="mono": + ./run.sh just ports/stm32/boards/Passport/bootloader/build {{screen}} # Run the built firmware through SHA256 verify-sha sha screen="mono": - #!/usr/bin/env bash - sha=$(shasum -a 256 ports/stm32/build-Passport/firmware-{{uppercase(screen)}}.bin | awk '{print $1}') + #!/usr/bin/env bash - if [ -z "${sha}" ]; then - exit 1 - fi + sha=$(shasum -a 256 ports/stm32/build-Passport/firmware-{{uppercase(screen)}}.bin | awk '{print $1}') - echo -e "Expected SHA:\t{{sha}}" - echo -e "Actual SHA:\t${sha}" - if [ "$sha" = "{{sha}}" ]; then - echo "Hashes match!" - else - echo "ERROR: Hashes DO NOT match!" - exit 1 - fi + if [ -z "${sha}" ]; then + exit 1 + fi + + echo -e "Expected SHA:\t{{sha}}" + echo -e "Actual SHA:\t${sha}" + if [ "$sha" = "{{sha}}" ]; then + echo "Hashes match!" + else + echo "ERROR: Hashes DO NOT match!" + exit 1 + fi +# Build tools. tools: build-add-secrets build-cosign # Build the add-secrets tool. -build-add-secrets: (run-in-docker "make -C ports/stm32/boards/Passport/tools/add-secrets") +build-add-secrets: + ./run.sh make -C ports/stm32/boards/Passport/tools/add-secrets # Build the cosign tool. -build-cosign: (run-in-docker "make -C ports/stm32/boards/Passport/tools/cosign") +build-cosign: + ./run.sh make -C ports/stm32/boards/Passport/tools/cosign # Sign the built firmware using a private key and the cosign tool -sign keypath version screen="mono": (build-firmware screen) (build-cosign) (run-in-docker ("just cosign_filepath=build-Passport/firmware-" + uppercase(screen) + ".bin cosign_keypath=" + keypath + " ports/stm32/sign " + version + " " + screen)) +sign keypath version screen="mono": (build-firmware screen) (build-cosign) + ./run.sh just cosign_filepath=build-Passport/firmware-{{uppercase(screen)}}.bin \ + cosign_keypath={{keypath}} \ + {{version}} \ + {{screen}} \ + ports/stm32/sign # Clean firmware build -clean: (run-in-docker "just ports/stm32/clean") +clean: + ./run.sh just ports/stm32/clean # Clean bootloader build -clean-firmware: (run-in-docker "just ports/stm32/clean") - -# Clean bootloader build -clean-bootloader: (run-in-docker "just ports/stm32/boards/Passport/bootloader/clean") +clean-bootloader: + ./run.sh just ports/stm32/boards/Passport/bootloader/clean # Clean simulator build -clean-simulator: (run-in-docker "just simulator/clean") +clean-simulator: + just simulator/clean # Build simulator -build-simulator screen="mono": (run-in-docker ("just simulator/build " + screen)) +build-simulator screen="mono": + just simulator/build {{screen}} # Run the simulator. sim screen="mono" ext="": @@ -69,18 +83,20 @@ test: cd ports/stm32/boards/Passport/modules/tests; python3 -m pytest . --simulatordir=$(pwd)/simulator # Lint the codebase. -lint: (run-in-docker "just ports/stm32/lint") (run-in-docker "just extmod/foundation-rust/lint") - -[private] -mpy-cross: (run-in-docker "make -C mpy-cross PROG=mpy-cross-docker BUILD=build-docker") - -[private] -run-in-docker command: - docker run --rm -v "$PWD":/workspace \ - -u $(id -u):$(id -g) \ - -v $(pwd):/workspace \ - -w /workspace \ - -e MPY_CROSS="/workspace/mpy-cross/mpy-cross-docker" \ - --entrypoint bash \ - ${DOCKER_IMAGE} \ - -c 'export PATH=$PATH:/workspace/ports/stm32/boards/Passport/tools/cosign/x86/release;{{command}}' +lint: + ./run.sh just ports/stm32/lint + ./run.sh just extmod/foundation-rust/lint + +# Build mpy-cross. +mpy-cross: + #!/usr/bin/env bash + set -e + + if [ "$USE_DOCKER" = true ]; + then + ./run.sh make -C mpy-cross/ \ + PROG=mpy-cross-docker \ + BUILD=build-docker + else + ./run.sh make -C mpy-cross/ + fi diff --git a/run.sh b/run.sh new file mode 100755 index 000000000..11b017cfc --- /dev/null +++ b/run.sh @@ -0,0 +1,44 @@ +#!/usr/bin/env bash +# SPDX-FileCopyrightText: © 2021 Foundation Devices, Inc. +# SPDX-License-Identifier: GPL-3.0-or-later + +set -e + +USER_UID=$(id -u) +USER_GID=$(id -g) + +# These can be overriden, for example: +# +# DOCKER='sudo docker' ./run.sh ... +# +# In order to build on systems where the user is not on the docker +# group. +DOCKER="${DOCKER:-docker}" +IN_DOCKER="${IN_DOCKER:-false}" +USE_DOCKER="${USE_DOCKER:-true}" +DOCKER_IMAGE="${DOCKER_IMAGE:-foundation-devices/passport2:latest}" +CONTAINER_UID=${CONTAINER_UID:-$USER_UID} +CONTAINER_GID=${CONTAINER_GID:-$USER_GID} + +# Retrieve the directory where the script is located. +# +# From: +# https://stackoverflow.com/questions/59895/how-do-i-get-the-directory-where-a-bash-script-is-located-from-within-the-script +SOURCE=${BASH_SOURCE[0]} +while [ -L "$SOURCE" ]; do # resolve $SOURCE until the file is no longer a symlink + DIR=$( cd -P "$( dirname "$SOURCE" )" >/dev/null 2>&1 && pwd ) + SOURCE=$(readlink "$SOURCE") + [[ $SOURCE != /* ]] && SOURCE=$DIR/$SOURCE # if $SOURCE was a relative symlink, we need to resolve it relative to the path where the symlink file was located +done +DIR=$( cd -P "$( dirname "$SOURCE" )" >/dev/null 2>&1 && pwd ) + +if [ "$IN_DOCKER" = true ] || [ "$USE_DOCKER" = false ]; +then + $@ +else + ${DOCKER} run --rm \ + --volume $DIR:/workspace \ + --user ${CONTAINER_UID}:${CONTAINER_GID} \ + ${DOCKER_IMAGE} \ + "$*" +fi