diff --git a/.github/dependabot.yml b/.github/dependabot.yml index ac63c45..c996bec 100644 --- a/.github/dependabot.yml +++ b/.github/dependabot.yml @@ -9,6 +9,12 @@ updates: directory: "/" schedule: interval: "daily" + groups: + baseimage-dependencies: + patterns: + - "tiiuae/fog-ros-sdk" + - "tiiuae/fog-ros-baseimage-builder" + - "tiiuae/fog-ros-baseimage" - package-ecosystem: "github-actions" directory: "/" schedule: diff --git a/.github/workflows/tii-gremsy.yaml b/.github/workflows/tii-gremsy.yaml index b9efe33..9e3574f 100644 --- a/.github/workflows/tii-gremsy.yaml +++ b/.github/workflows/tii-gremsy.yaml @@ -1,55 +1,53 @@ name: Build on: - repository_dispatch: - types: [fog-ros-baseimage-update] push: + pull_request: workflow_dispatch: +permissions: + contents: read + packages: write + jobs: build: runs-on: ubuntu-latest steps: - - uses: actions/checkout@v3 + - uses: actions/checkout@v4 with: submodules: recursive - - uses: docker/setup-buildx-action@v2 - - - name: Set image tag format without suffix - run: | - echo "IMAGE_TAG_FORMAT=type=sha" >> $GITHUB_ENV - if: github.event_name == 'push' + - name: Setup QEMU + uses: docker/setup-qemu-action@v2 + with: + platforms: amd64,riscv64,arm64 - - name: Set image tag format with suffix - # it is possible that run_number should be used instead run_attempt - # run_attempt is unique number on every run and run_attempt resets to 1 if re-build is not used - # content of image_sha_tag_suffix is defined in fog-ros-baseimage dispatcher workflow. - run: | - echo "IMAGE_TAG_FORMAT=type=sha,suffix=-${{ github.event.client_payload.image_sha_tag_suffix }}" >> $GITHUB_ENV - if: github.event_name == 'repository_dispatch' + - uses: docker/setup-buildx-action@v3 - name: Docker meta id: meta - uses: docker/metadata-action@v4 + uses: docker/metadata-action@v5 with: images: ghcr.io/tiiuae/tii-gremsy tags: | type=ref,event=branch + type=ref,event=pr type=semver,pattern={{version}} - type=raw,value=latest - ${{ env.IMAGE_TAG_FORMAT }} + type=sha + type=raw,value=latest,enable=${{ endsWith(github.ref, github.event.repository.default_branch) }} + - name: Login to GitHub Container Registry - uses: docker/login-action@v2 + uses: docker/login-action@v3 with: registry: ghcr.io username: ${{ github.actor }} password: ${{ secrets.GITHUB_TOKEN }} - name: Build container image and push - uses: docker/build-push-action@v4 + uses: docker/build-push-action@v5 with: context: . + platforms: linux/amd64,linux/riscv64,linux/arm64 push: true tags: ${{ steps.meta.outputs.tags }} labels: ${{ steps.meta.outputs.labels }} diff --git a/Dockerfile b/Dockerfile index 962a61e..b7588fa 100644 --- a/Dockerfile +++ b/Dockerfile @@ -1,21 +1,29 @@ -FROM ghcr.io/tiiuae/fog-ros-baseimage-builder:v2.1.0 AS builder +FROM --platform=${BUILDPLATFORM:-linux/amd64} ghcr.io/tiiuae/fog-ros-sdk:v3.0.1-${TARGETARCH:-amd64} AS builder -COPY . /main_ws/src/ +# Must be defined another time after "FROM" keyword. +ARG TARGETARCH -# this: -# 1) builds the application -# 2) packages the application as .deb in /main_ws/ +# SRC_DIR environment variable is defined in the fog-ros-sdk image. +# The same workspace path is used by all ROS2 components. +# See: https://github.com/tiiuae/fog-ros-baseimage/blob/main/Dockerfile.sdk_builder +COPY . $SRC_DIR/ros2_gremsy -RUN /packaging/build.sh +RUN /packaging/build_colcon_sdk.sh ${TARGETARCH:-amd64} +# Even though it is possible to tar the install directory for retrieving it later in runtime image, +# the tar extraction in arm64 emulated on arm64 is still slow. So, we copy the install directory instead # ▲ runtime ──┐ # └── build ▼ -FROM ghcr.io/tiiuae/fog-ros-baseimage:v2.1.0 +FROM ghcr.io/tiiuae/fog-ros-baseimage:v3.0.1 -ENTRYPOINT exec ros-with-env ros2 run ros2_gremsy gremsy_node --ros-args --remap __ns:=/$DRONE_DEVICE_ID -p com_port:=/dev/ttyUSB0 +# ENTRYPOINT exec ros-with-env ros2 run ros2_gremsy gremsy_node --ros-args --remap __ns:=/$DRONE_DEVICE_ID -p com_port:=/dev/ttyUSB0 +ENTRYPOINT [ "/entrypoint.sh" ] -COPY --from=builder /main_ws/ros-*-ros2-gremsy_*_amd64.deb /ros2_gremsy.deb +COPY entrypoint.sh /entrypoint.sh -RUN apt update && apt install -y --no-install-recommends ./ros2_gremsy.deb \ - && rm /ros2_gremsy.deb +# WORKSPACE_DIR environment variable is defined in the fog-ros-baseimage. +# The same installation directory is used by all ROS2 components. +# See: https://github.com/tiiuae/fog-ros-baseimage/blob/main/Dockerfile +WORKDIR $WORKSPACE_DIR +COPY --from=builder $WORKSPACE_DIR/install install diff --git a/entrypoint.sh b/entrypoint.sh new file mode 100755 index 0000000..79fd730 --- /dev/null +++ b/entrypoint.sh @@ -0,0 +1,41 @@ +#!/bin/bash -e +_term() { + # FILL UP PROCESS SEARCH PATTERN HERE TO FIND PROPER PROCESS FOR SIGINT: + pattern="component_container_mt" + + pid_value="$(ps -e | grep $pattern | grep -v grep | awk '{ print $1 }')" + if [ "$pid_value" != "" ]; then + pid=$pid_value + echo "Send SIGINT to pid $pid" + else + pid=1 + echo "Pattern not found, send SIGINT to pid $pid" + fi + kill -s SIGINT $pid +} +# Use SIGTERM or TERM, does not seem to make any difference. +trap _term TERM + +ros-with-env ros2 run ros2_gremsy gremsy_node --ros-args --remap __ns:=/$DRONE_DEVICE_ID -p com_port:=/dev/ttyUSB0 & +child=$! + +echo "Waiting for pid $child" +# * Calling "wait" will then wait for the job with the specified by $child to finish, or for any signals to be fired. +# Due to "or for any signals to be fired", "wait" will also handle SIGTERM and it will shutdown before +# the node ends gracefully. +# The solution is to add a second "wait" call and remove the trap between the two calls. +# * Do not use -e flag in the first wait call because wait will exit with error after catching SIGTERM. +set +e +wait $child +set -e +trap - TERM +wait $child +RESULT=$? + +if [ $RESULT -ne 0 ]; then + echo "ERROR: Ros2 Gresmy node failed with code $RESULT" >&2 + exit $RESULT +else + echo "INFO: Ros2 Gresmy node finished successfully, but returning 125 code for docker to restart properly." >&2 + exit 125 +fi