diff --git a/.github/workflows/tiiuae-pixhawk-and-saluki.yaml b/.github/workflows/tiiuae-pixhawk-and-saluki.yaml index 4b14fe7578a0..f26dffb60110 100644 --- a/.github/workflows/tiiuae-pixhawk-and-saluki.yaml +++ b/.github/workflows/tiiuae-pixhawk-and-saluki.yaml @@ -11,7 +11,7 @@ on: workflow_dispatch: inputs: jfrog-upload: - description: 'upload to Artifactory' + description: 'upload to UAE Artifactory' required: false default: false type: boolean diff --git a/Tools/px_uploader.Dockerfile b/Tools/px_uploader.Dockerfile index 21672738036c..1757676aa39b 100644 --- a/Tools/px_uploader.Dockerfile +++ b/Tools/px_uploader.Dockerfile @@ -2,24 +2,8 @@ FROM python:alpine3.14 ARG saluki_fpga_directory ARG SALUKI_FILE_INFO_JSON=saluki_file_info.json - -# run this with something like: -# -# $ docker run --rm -it --network=host --device=/dev/ttyS7:/dev/px4serial px4-fw-updater \ -# --udp-addr=192.168.200.101 \ -# --udp-port=14541 \ -# --port=/dev/px4serial \ -# --baud-bootloader=2000000 \ -# px4_fmu-v5_ssrc.px4 - -# This gets built in environment with somewhat unorthodox paths: -# - The build context is at / -# - The repository itself is mounted in /px4-firmware/ -# - Built firmware files are in /bin/ -# -# ("/" above is relative to GH action runner home dir) -# (see .github/workflows/tiiuae-pixhawk.yaml) - +ARG PX4_EXPORT_DIR +ENV PX4_EXPORT_DIR=$PX4_EXPORT_DIR COPY $saluki_fpga_directory /firmware/fpga COPY $SALUKI_FILE_INFO_JSON /$SALUKI_FILE_INFO_JSON @@ -27,6 +11,9 @@ WORKDIR /firmware ENTRYPOINT ["/entrypoint.sh"] +# tools needed to extract binaries from px4 files +RUN apk add pigz jq + # dependency of px_uploader.py RUN pip3 install --user pyserial diff --git a/Tools/px_uploader.entrypoint b/Tools/px_uploader.entrypoint index 1d9b7f87b36b..e8a3791f8ae6 100755 --- a/Tools/px_uploader.entrypoint +++ b/Tools/px_uploader.entrypoint @@ -1,13 +1,99 @@ #!/bin/sh -e -aframe="" -if [ ! -z "$AIRFRAME" ]; then - aframe="--airframe ${AIRFRAME}" -fi +SALUKI_FILE_INFO_JSON="/saluki_file_info.json" +TEMP_JSON=${SALUKI_FILE_INFO_JSON}.tmp + + +extract_bin_from_px4() { + local px4_file=$1 + local target_dir=$2 + local target=${target_dir}/$(basename ${px4_file%.px4}).bin + + # check file exists + if [ ! -f $px4_file ]; then + echo "File $px4_file does not exist" + exit 1 + fi + + echo "Extracting $target from $px4_file" + # binary is stored in the 'image' field of the json file + # as base64 encoded and gzipped + cat ${px4_file} | jq -r '.image' | base64 -d | pigz -d > $target + + # px4 build timestamp is included in px4 file + build_timestamp=$(cat ${px4_file} | jq -r '.build_time') + + validation_file=${target_dir}/$(basename ${px4_file%.px4})-validation.txt + generate_validation_file ${px4_file} ${validation_file} ${build_timestamp} +} + +function generate_validation_file() { + local px4_filename=${1} + local validation_file=${2} + local timestamp=${3} + echo "generating validation file for ${px4_filename} to ${validation_file}" + + # get the file info from the SALUKI_FILE_INFO_JSON.json + # new filename to .bin without the path + px4_bin_filename=$(basename ${px4_filename%.px4}).bin + + # update filename and file_type + saluki_file_info=$(cat ${SALUKI_FILE_INFO_JSON} | + jq -c '.files[] | select (.filename | contains("'${px4_filename}'")) | + .filename = "'${px4_bin_filename}'" | + .type = "px4-bin"') + + # Add the build timestamp + saluki_file_info=$(echo ${saluki_file_info} | + jq -c 'select (.filename | contains("'${px4_bin_filename}'"))' | + jq '. += {"build_time":"'${timestamp}'"}') + echo ${saluki_file_info} > ${validation_file} + + # modify json in saluki_file_info variable so that the element is in an files array + # saluki_file_info=$(echo ${saluki_file_info} | jq -c '{files: [.]}') + + # append file info to temporary file + echo ${TEMP_JSON} + + # if the temp json file does not exist, create it with the file info + if [ ! -f ${TEMP_JSON} ]; then + # print the object into "files" array + echo ${saluki_file_info} | jq -c '{files: [.] }' >${TEMP_JSON} + # if the temp json file exists, append the file info to it + else + # need to use temp file for this round as jq wont overwrite the input file + temp_round_file=${TEMP_JSON}.round + + # Read the existing JSON + json_content=$(cat "${TEMP_JSON}") + + # Add the new object to the "files" array using jq + updated_json=$(echo "$json_content" | jq --argjson obj "$saluki_file_info" '.files += [$obj]') + + # put the output to temp_round_file and then move it to the final temp json file + echo ${updated_json} >${temp_round_file} + mv ${temp_round_file} ${TEMP_JSON} + fi +} + +# export px4 files if the container is started with the PX4_EXPORT_DIR +if [ -n "$PX4_EXPORT_DIR" ]; then + echo "Exporting PX4 files to $PX4_EXPORT_DIR" + + # remove temp json file if it exists + if [ -f ${TEMP_JSON} ]; then + rm ${TEMP_JSON} + fi + + # find all px4 files in the firmware directory + for px4_file in /firmware/*.px4; do + extract_bin_from_px4 $px4_file $PX4_EXPORT_DIR + done -mode="" -if [ ! -z "$FLIGHT_MODE" ]; then - mode="--flightmode ${FLIGHT_MODE}" + # move temp json file to the final json file + mv ${TEMP_JSON} $PX4_EXPORT_DIR/${SALUKI_FILE_INFO_JSON} fi -/bin/px_uploader.py --port=/dev/px4serial --udp-addr=192.168.200.101 --baud-flightstack=57600,115200,1000000,2000000 --baud-bootloader=2000000 px4_fmu-v5x_ssrc-*.px4 ssrc_saluki-v1_default-*.px4 ssrc_saluki-v2_default-*.px4 +# keep the container running so px4 update can get the +# px4 firmware files from the container +# tail -f /dev/null