From d074d99f24d41b783df7403c0524c756e2f86ccd Mon Sep 17 00:00:00 2001 From: Jean-Pierre Busch Date: Wed, 24 May 2023 14:45:59 +0200 Subject: [PATCH 001/159] test docker-based action --- Dockerfile | 191 ++------------------------------------------------ action.yml | 16 +++++ entrypoint.sh | 32 ++------- 3 files changed, 26 insertions(+), 213 deletions(-) create mode 100644 action.yml diff --git a/Dockerfile b/Dockerfile index 85b083c..9761d19 100644 --- a/Dockerfile +++ b/Dockerfile @@ -1,187 +1,8 @@ -ARG BASE_IMAGE +# Container image that runs your code +FROM alpine:3.10 -############ dependencies ###################################################### -FROM ${BASE_IMAGE} as dependencies +# Copies your code file from your action repository to the filesystem path `/` of the container +COPY entrypoint.sh /entrypoint.sh -USER root -SHELL ["/bin/bash", "-c"] -ARG DEBIAN_FRONTEND=noninteractive - -# create workspace folder structure -ENV WORKSPACE=/docker-ros/ws -WORKDIR $WORKSPACE -RUN mkdir -p src/target src/upstream src/downstream - -# setup keys and sources.list for ROS packages -ARG ROS_DISTRO -ENV ROS_DISTRO=${ROS_DISTRO} -RUN test -n "$ROS_DISTRO" || (echo "missing build-arg: ROS_DISTRO" && false) -RUN apt-get update && \ - apt-get install -y curl gnupg && \ - apt-key adv --keyserver hkp://keyserver.ubuntu.com:80 --recv-keys C1CF6E31E6BADE8868B172B4F42ED6FBAB17C654 && \ - echo "deb http://packages.ros.org/ros/ubuntu focal main" > /etc/apt/sources.list.d/ros1-latest.list && \ - curl -sSL https://raw.githubusercontent.com/ros/rosdistro/master/ros.key -o /usr/share/keyrings/ros-archive-keyring.gpg && \ - echo "deb [arch=$(dpkg --print-architecture) signed-by=/usr/share/keyrings/ros-archive-keyring.gpg] http://packages.ros.org/ros2/ubuntu $(. /etc/os-release && echo $UBUNTU_CODENAME) main" | tee /etc/apt/sources.list.d/ros2.list > /dev/null && \ - rm -rf /var/lib/apt/lists/* - -# install ROS bootstrapping tools -RUN apt-get update && \ - apt-get install -y \ - git \ - python3-rosdep \ - python3-vcstool \ - && rm -rf /var/lib/apt/lists/* - -# copy contents of repository -COPY . src/repository - -# if repository is a top-level package, move contents to folder -RUN shopt -s dotglob && \ - if [[ -f "src/repository/package.xml" ]]; then \ - PACKAGE_NAME=$(sed -n 's/.*\(.*\)<\/name>.*/\1/p' src/repository/package.xml) && \ - mkdir -p src/target/${PACKAGE_NAME} && \ - mv src/repository/* src/target/${PACKAGE_NAME} ; \ - else \ - mv src/repository/* src/target ; \ - fi && \ - rm -r src/repository - -# clone .repos upstream dependencies -ARG GIT_HTTPS_URL=https://gitlab.ika.rwth-aachen.de -ARG GIT_HTTPS_USER= -ARG GIT_HTTPS_PASSWORD= -RUN if [ ! -z ${GIT_HTTPS_USER} ]; then \ - git config --global url.https://${GIT_HTTPS_USER}:${GIT_HTTPS_PASSWORD}@gitlab.ika.rwth-aachen.de.insteadOf ${GIT_HTTPS_URL} ; \ - fi -COPY docker/docker-ros/recursive_vcs_import.py /usr/local/bin -RUN apt-get update && \ - apt-get install -y python-is-python3 && \ - rm -rf /var/lib/apt/lists/* -RUN /usr/local/bin/recursive_vcs_import.py src src/upstream - -# create install script with list of rosdep dependencies -RUN echo "set -e" >> $WORKSPACE/.install-dependencies.sh && \ - apt-get update && \ - rosdep init || true && \ - rosdep update && \ - export OS="ubuntu:$(lsb_release -c | awk '{print $2}')" && \ - if [[ "$ROS_DISTRO" = "rolling" && "$OS" = "ubuntu:focal" ]]; then export OS="ubuntu:jammy"; fi && \ - set -o pipefail && \ - ROS_PACKAGE_PATH=$(pwd):$ROS_PACKAGE_PATH rosdep install --os $OS -y --simulate --from-paths src --ignore-src | tee -a $WORKSPACE/.install-dependencies.sh && \ - chmod +x $WORKSPACE/.install-dependencies.sh && \ - rm -rf /var/lib/apt/lists/* - -# add additionally specified apt dependencies to install script -RUN echo "apt-get install -y \\" >> $WORKSPACE/.install-dependencies.sh && \ - set -o pipefail && \ - find . -type f -name "additional.apt-dependencies" -exec cat {} \; | awk '{print " " $0 " \\"}' >> $WORKSPACE/.install-dependencies.sh && \ - echo ";" >> $WORKSPACE/.install-dependencies.sh - -# add custom installation commands to install script -RUN find . -type f -name "custom.sh" -exec cat {} >> $WORKSPACE/.install-dependencies.sh \; - -# remove now obsolete docker folder from copied repository content to avoid redundancies -RUN rm -rf src/target/docker - -############ dependencies-install ############################################## -FROM ${BASE_IMAGE} AS dependencies-install -ARG TARGETARCH -ARG GIT_HTTPS_URL -ARG GIT_HTTPS_USER -ARG GIT_HTTPS_PASSWORD -ENV TARGETARCH=${TARGETARCH} -ENV DOCKER_ROS=1 - -USER root -SHELL ["/bin/bash", "-c"] -ARG DEBIAN_FRONTEND=noninteractive - -# user setup -ENV DOCKER_USER=dockeruser -ENV DOCKER_UID= -ENV DOCKER_GID= - -# ROS setup -ENV RCUTILS_COLORIZED_OUTPUT=1 -ENV WORKSPACE=/docker-ros/ws -ENV COLCON_HOME=$WORKSPACE/.colcon -WORKDIR $WORKSPACE - -# setup keys and sources.list for ROS packages -ARG ROS_DISTRO -ENV ROS_DISTRO=${ROS_DISTRO} -RUN test -n "$ROS_DISTRO" || (echo "missing build-arg: ROS_DISTRO" && false) -RUN apt-get update && \ - apt-get install -y curl gnupg && \ - apt-key adv --keyserver hkp://keyserver.ubuntu.com:80 --recv-keys C1CF6E31E6BADE8868B172B4F42ED6FBAB17C654 && \ - echo "deb http://packages.ros.org/ros/ubuntu focal main" > /etc/apt/sources.list.d/ros1-latest.list && \ - curl -sSL https://raw.githubusercontent.com/ros/rosdistro/master/ros.key -o /usr/share/keyrings/ros-archive-keyring.gpg && \ - echo "deb [arch=$(dpkg --print-architecture) signed-by=/usr/share/keyrings/ros-archive-keyring.gpg] http://packages.ros.org/ros2/ubuntu $(. /etc/os-release && echo $UBUNTU_CODENAME) main" | tee /etc/apt/sources.list.d/ros2.list > /dev/null && \ - rm -rf /var/lib/apt/lists/* - -# copy contents of files-folder into image -ADD docker/files* /docker-ros/files/ - -# install essential ROS CLI tools -RUN apt-get update && \ - apt-get install -y \ - build-essential \ - gosu \ - && source /opt/ros/$ROS_DISTRO/setup.bash && \ - if [ "$ROS_VERSION" == "1" ]; then \ - apt-get install -y \ - python3-catkin-tools ; \ - elif [ "$ROS_VERSION" == "2" ]; then \ - apt-get install -y \ - python3-colcon-common-extensions ; \ - fi \ - && rm -rf /var/lib/apt/lists/* - -# copy install script from dependencies stage -COPY --from=dependencies $WORKSPACE/.install-dependencies.sh $WORKSPACE/.install-dependencies.sh - -# install dependencies -RUN apt-get update && \ - $WORKSPACE/.install-dependencies.sh && \ - rm -rf /var/lib/apt/lists/* - -# source ROS -RUN echo "source /opt/ros/$ROS_DISTRO/setup.bash" >> ~/.bashrc - -# set entrypoint -COPY docker/docker-ros/entrypoint.sh / -ENTRYPOINT ["/entrypoint.sh"] - -############ dev ############################################################### -FROM dependencies-install as dev - -# copy contents of repository from dependencies stage -COPY --from=dependencies $WORKSPACE/src $WORKSPACE/src - -CMD ["bash"] - -############ build ############################################################# -FROM dev as build - -# build ROS workspace -RUN if [ -x "$(command -v colcon)" ]; then \ - source /opt/ros/${ROS_DISTRO}/setup.bash && \ - colcon build --cmake-args -DCMAKE_BUILD_TYPE=Release ; \ - elif [ -x "$(command -v catkin)" ]; then \ - catkin config --install --extend /opt/ros/${ROS_DISTRO} && \ - catkin build -DCMAKE_BUILD_TYPE=Release --force-color --no-status --summarize ; \ - fi - -############ run ############################################################### -FROM dependencies-install as run - -# copy ROS install space from build stage -COPY --from=build $WORKSPACE/install install -RUN ldconfig -RUN echo "[[ -f $WORKSPACE/devel/setup.bash ]] && source $WORKSPACE/devel/setup.bash" >> ~/.bashrc && \ - echo "[[ -f $WORKSPACE/install/setup.bash ]] && source $WORKSPACE/install/setup.bash" >> ~/.bashrc - -# setup command -ARG COMMAND -ENV DEFAULT_CMD=${COMMAND} -CMD ${DEFAULT_CMD} +# Code file to execute when the docker container starts up (`entrypoint.sh`) +ENTRYPOINT ["/entrypoint.sh"] \ No newline at end of file diff --git a/action.yml b/action.yml new file mode 100644 index 0000000..0011139 --- /dev/null +++ b/action.yml @@ -0,0 +1,16 @@ +# action.yml +name: 'Hello World' +description: 'Greet someone and record the time' +inputs: + who-to-greet: # id of input + description: 'Who to greet' + required: true + default: 'World' +outputs: + time: # id of output + description: 'The time we greeted you' +runs: + using: 'docker' + image: 'Dockerfile' + args: + - ${{ inputs.who-to-greet }} \ No newline at end of file diff --git a/entrypoint.sh b/entrypoint.sh index 5771f19..297a521 100755 --- a/entrypoint.sh +++ b/entrypoint.sh @@ -1,29 +1,5 @@ -#!/bin/bash -set -e +#!/bin/sh -l -# source ROS workspace -source /opt/ros/$ROS_DISTRO/setup.bash -[[ -f $WORKSPACE/devel/setup.bash ]] && source $WORKSPACE/devel/setup.bash -[[ -f $WORKSPACE/install/setup.bash ]] && source $WORKSPACE/install/setup.bash - -# exec as dockeruser with configured UID/GID -if [[ $DOCKER_UID && $DOCKER_GID ]]; then - groupadd -g $DOCKER_GID $DOCKER_USER - useradd -s /bin/bash \ - -u $DOCKER_UID \ - -g $DOCKER_USER \ - --create-home \ - --home-dir /home/$DOCKER_USER \ - --groups sudo,video \ - --password "$(openssl passwd -1 $DOCKER_USER)" \ - $DOCKER_USER && \ - touch /home/$DOCKER_USER/.sudo_as_admin_successful - chown -R $DOCKER_USER:$DOCKER_USER $WORKSPACE - ln -s $WORKSPACE /home/$DOCKER_USER/ws - cd /home/$DOCKER_USER/ws - cp /root/.bashrc /home/$DOCKER_USER - chown $DOCKER_USER:$DOCKER_USER /home/$DOCKER_USER/.bashrc - exec gosu $DOCKER_USER "$@" -else - exec "$@" -fi +echo "Hello $1" +time=$(date) +echo "time=$time" >> $GITHUB_OUTPUT \ No newline at end of file From 55f30564b0ec3d5b36e3d0c579fc9ab7155d53f4 Mon Sep 17 00:00:00 2001 From: Jean-Pierre Busch Date: Wed, 24 May 2023 15:00:46 +0200 Subject: [PATCH 002/159] test github repo var --- entrypoint.sh | 1 + 1 file changed, 1 insertion(+) diff --git a/entrypoint.sh b/entrypoint.sh index 297a521..6184045 100755 --- a/entrypoint.sh +++ b/entrypoint.sh @@ -1,5 +1,6 @@ #!/bin/sh -l echo "Hello $1" +echo "REPO $GITHUB_REPOSITORY" time=$(date) echo "time=$time" >> $GITHUB_OUTPUT \ No newline at end of file From c84f5f054c04a967dddebd63e7c941af02351fb8 Mon Sep 17 00:00:00 2001 From: Jean-Pierre Busch Date: Wed, 24 May 2023 15:48:14 +0200 Subject: [PATCH 003/159] add workflow for triggering docker-ros-ci pipeline --- .github/workflows/main.yml | 13 +++++++++++++ 1 file changed, 13 insertions(+) create mode 100644 .github/workflows/main.yml diff --git a/.github/workflows/main.yml b/.github/workflows/main.yml new file mode 100644 index 0000000..5a1f738 --- /dev/null +++ b/.github/workflows/main.yml @@ -0,0 +1,13 @@ +on: [push] + +jobs: + trigger_workflow: + runs-on: ubuntu-latest + steps: + - name: Trigger Other Repository Workflow + uses: peter-evans/repository-dispatch@v2 + with: + token: ${{ secrets.PAT }} # Personal Access Token with appropriate permissions + repository: ika-rwth-aachen/docker-ros-ci + event-type: my-event + client-payload: '{"ref": "feature/github-workflow"}' \ No newline at end of file From 60d6bee909951140279abec340cf571d05abcb9f Mon Sep 17 00:00:00 2001 From: Jean-Pierre Busch Date: Wed, 24 May 2023 16:21:21 +0200 Subject: [PATCH 004/159] test trigger by api --- .github/workflows/main.yml | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/.github/workflows/main.yml b/.github/workflows/main.yml index 5a1f738..393d378 100644 --- a/.github/workflows/main.yml +++ b/.github/workflows/main.yml @@ -10,4 +10,7 @@ jobs: token: ${{ secrets.PAT }} # Personal Access Token with appropriate permissions repository: ika-rwth-aachen/docker-ros-ci event-type: my-event - client-payload: '{"ref": "feature/github-workflow"}' \ No newline at end of file + client-payload: '{"ref": "feature/github-workflow"}' + - name: Trigger by API + run: | + curl -X POST -H "Authorization: Bearer ${{ secrets.PAT }}" -H "Accept: application/vnd.github.v3+json" -d '{"ref":"feature/github-workflow"}' "https://api.github.com/repos/ika-rwth-aachen/docker-ros-ci/actions/workflows/main.yml/dispatches" \ No newline at end of file From 43ca979c2b73785619a97e743fa9b443cf33a823 Mon Sep 17 00:00:00 2001 From: Jean-Pierre Busch Date: Wed, 24 May 2023 17:02:27 +0200 Subject: [PATCH 005/159] watch workflow --- .github/workflows/main.yml | 29 +++++++++++++++++++++++++---- 1 file changed, 25 insertions(+), 4 deletions(-) diff --git a/.github/workflows/main.yml b/.github/workflows/main.yml index 393d378..a0e19a2 100644 --- a/.github/workflows/main.yml +++ b/.github/workflows/main.yml @@ -2,15 +2,36 @@ on: [push] jobs: trigger_workflow: + name: Trigger docker-ros-ci workflow runs-on: ubuntu-latest steps: - - name: Trigger Other Repository Workflow + - name: Trigger docker-ros-ci using repository-dispatch + id: repository-dispatch uses: peter-evans/repository-dispatch@v2 with: token: ${{ secrets.PAT }} # Personal Access Token with appropriate permissions repository: ika-rwth-aachen/docker-ros-ci + ref: feature/github-workflow event-type: my-event - client-payload: '{"ref": "feature/github-workflow"}' - - name: Trigger by API + #client-payload: '{"ref": "feature/github-workflow"}' + # - name: Trigger by API + # run: | + # curl -X POST -H "Authorization: Bearer ${{ secrets.PAT }}" -H "Accept: application/vnd.github.v3+json" -d '{"ref":"feature/github-workflow"}' "https://api.github.com/repos/ika-rwth-aachen/docker-ros-ci/actions/workflows/main.yml/dispatches" + watch_workflow: + name: Watch docker-ros-ci workflow run + runs-on: ubuntu-latest + needs: trigger_workflow + steps: + - name: Check Pipeline Status + id: check_status run: | - curl -X POST -H "Authorization: Bearer ${{ secrets.PAT }}" -H "Accept: application/vnd.github.v3+json" -d '{"ref":"feature/github-workflow"}' "https://api.github.com/repos/ika-rwth-aachen/docker-ros-ci/actions/workflows/main.yml/dispatches" \ No newline at end of file + while true; do + sleep 30 + PIPELINE_STATUS=$(curl --silent --header "Authorization: Bearer ${{ secrets.PAT }}" "https://api.github.com/repos/owner/other-repository/actions/runs/${{ needs.trigger_pipeline.outputs.dispatch.outputs.run_id }}" | jq -r '.status') + echo "Pipeline status: $PIPELINE_STATUS" + if [[ $PIPELINE_STATUS == "completed" ]]; then + break + elif [[ $PIPELINE_STATUS == "failure" || $PIPELINE_STATUS == "cancelled" ]]; then + exit 1 + fi + done \ No newline at end of file From 7767ac47d16bc6d2f58f4472fb946a0af565e35b Mon Sep 17 00:00:00 2001 From: Jean-Pierre Busch Date: Wed, 24 May 2023 17:08:18 +0200 Subject: [PATCH 006/159] test --- .github/workflows/main.yml | 1 + 1 file changed, 1 insertion(+) diff --git a/.github/workflows/main.yml b/.github/workflows/main.yml index a0e19a2..932382a 100644 --- a/.github/workflows/main.yml +++ b/.github/workflows/main.yml @@ -25,6 +25,7 @@ jobs: - name: Check Pipeline Status id: check_status run: | + echo TEST ${{ needs.trigger_pipeline.outputs.dispatch.outputs.run_id }} while true; do sleep 30 PIPELINE_STATUS=$(curl --silent --header "Authorization: Bearer ${{ secrets.PAT }}" "https://api.github.com/repos/owner/other-repository/actions/runs/${{ needs.trigger_pipeline.outputs.dispatch.outputs.run_id }}" | jq -r '.status') From 025c4cd0e88cf2320e1440a9e5c8446cfd1552e3 Mon Sep 17 00:00:00 2001 From: Jean-Pierre Busch Date: Wed, 24 May 2023 18:01:39 +0200 Subject: [PATCH 007/159] switch to composite action --- Dockerfile | 191 ++++++++++++++++++++++++++++++++++++++++++++++++-- action.yml | 22 ++++-- entrypoint.sh | 33 +++++++-- 3 files changed, 228 insertions(+), 18 deletions(-) diff --git a/Dockerfile b/Dockerfile index 9761d19..85b083c 100644 --- a/Dockerfile +++ b/Dockerfile @@ -1,8 +1,187 @@ -# Container image that runs your code -FROM alpine:3.10 +ARG BASE_IMAGE -# Copies your code file from your action repository to the filesystem path `/` of the container -COPY entrypoint.sh /entrypoint.sh +############ dependencies ###################################################### +FROM ${BASE_IMAGE} as dependencies -# Code file to execute when the docker container starts up (`entrypoint.sh`) -ENTRYPOINT ["/entrypoint.sh"] \ No newline at end of file +USER root +SHELL ["/bin/bash", "-c"] +ARG DEBIAN_FRONTEND=noninteractive + +# create workspace folder structure +ENV WORKSPACE=/docker-ros/ws +WORKDIR $WORKSPACE +RUN mkdir -p src/target src/upstream src/downstream + +# setup keys and sources.list for ROS packages +ARG ROS_DISTRO +ENV ROS_DISTRO=${ROS_DISTRO} +RUN test -n "$ROS_DISTRO" || (echo "missing build-arg: ROS_DISTRO" && false) +RUN apt-get update && \ + apt-get install -y curl gnupg && \ + apt-key adv --keyserver hkp://keyserver.ubuntu.com:80 --recv-keys C1CF6E31E6BADE8868B172B4F42ED6FBAB17C654 && \ + echo "deb http://packages.ros.org/ros/ubuntu focal main" > /etc/apt/sources.list.d/ros1-latest.list && \ + curl -sSL https://raw.githubusercontent.com/ros/rosdistro/master/ros.key -o /usr/share/keyrings/ros-archive-keyring.gpg && \ + echo "deb [arch=$(dpkg --print-architecture) signed-by=/usr/share/keyrings/ros-archive-keyring.gpg] http://packages.ros.org/ros2/ubuntu $(. /etc/os-release && echo $UBUNTU_CODENAME) main" | tee /etc/apt/sources.list.d/ros2.list > /dev/null && \ + rm -rf /var/lib/apt/lists/* + +# install ROS bootstrapping tools +RUN apt-get update && \ + apt-get install -y \ + git \ + python3-rosdep \ + python3-vcstool \ + && rm -rf /var/lib/apt/lists/* + +# copy contents of repository +COPY . src/repository + +# if repository is a top-level package, move contents to folder +RUN shopt -s dotglob && \ + if [[ -f "src/repository/package.xml" ]]; then \ + PACKAGE_NAME=$(sed -n 's/.*\(.*\)<\/name>.*/\1/p' src/repository/package.xml) && \ + mkdir -p src/target/${PACKAGE_NAME} && \ + mv src/repository/* src/target/${PACKAGE_NAME} ; \ + else \ + mv src/repository/* src/target ; \ + fi && \ + rm -r src/repository + +# clone .repos upstream dependencies +ARG GIT_HTTPS_URL=https://gitlab.ika.rwth-aachen.de +ARG GIT_HTTPS_USER= +ARG GIT_HTTPS_PASSWORD= +RUN if [ ! -z ${GIT_HTTPS_USER} ]; then \ + git config --global url.https://${GIT_HTTPS_USER}:${GIT_HTTPS_PASSWORD}@gitlab.ika.rwth-aachen.de.insteadOf ${GIT_HTTPS_URL} ; \ + fi +COPY docker/docker-ros/recursive_vcs_import.py /usr/local/bin +RUN apt-get update && \ + apt-get install -y python-is-python3 && \ + rm -rf /var/lib/apt/lists/* +RUN /usr/local/bin/recursive_vcs_import.py src src/upstream + +# create install script with list of rosdep dependencies +RUN echo "set -e" >> $WORKSPACE/.install-dependencies.sh && \ + apt-get update && \ + rosdep init || true && \ + rosdep update && \ + export OS="ubuntu:$(lsb_release -c | awk '{print $2}')" && \ + if [[ "$ROS_DISTRO" = "rolling" && "$OS" = "ubuntu:focal" ]]; then export OS="ubuntu:jammy"; fi && \ + set -o pipefail && \ + ROS_PACKAGE_PATH=$(pwd):$ROS_PACKAGE_PATH rosdep install --os $OS -y --simulate --from-paths src --ignore-src | tee -a $WORKSPACE/.install-dependencies.sh && \ + chmod +x $WORKSPACE/.install-dependencies.sh && \ + rm -rf /var/lib/apt/lists/* + +# add additionally specified apt dependencies to install script +RUN echo "apt-get install -y \\" >> $WORKSPACE/.install-dependencies.sh && \ + set -o pipefail && \ + find . -type f -name "additional.apt-dependencies" -exec cat {} \; | awk '{print " " $0 " \\"}' >> $WORKSPACE/.install-dependencies.sh && \ + echo ";" >> $WORKSPACE/.install-dependencies.sh + +# add custom installation commands to install script +RUN find . -type f -name "custom.sh" -exec cat {} >> $WORKSPACE/.install-dependencies.sh \; + +# remove now obsolete docker folder from copied repository content to avoid redundancies +RUN rm -rf src/target/docker + +############ dependencies-install ############################################## +FROM ${BASE_IMAGE} AS dependencies-install +ARG TARGETARCH +ARG GIT_HTTPS_URL +ARG GIT_HTTPS_USER +ARG GIT_HTTPS_PASSWORD +ENV TARGETARCH=${TARGETARCH} +ENV DOCKER_ROS=1 + +USER root +SHELL ["/bin/bash", "-c"] +ARG DEBIAN_FRONTEND=noninteractive + +# user setup +ENV DOCKER_USER=dockeruser +ENV DOCKER_UID= +ENV DOCKER_GID= + +# ROS setup +ENV RCUTILS_COLORIZED_OUTPUT=1 +ENV WORKSPACE=/docker-ros/ws +ENV COLCON_HOME=$WORKSPACE/.colcon +WORKDIR $WORKSPACE + +# setup keys and sources.list for ROS packages +ARG ROS_DISTRO +ENV ROS_DISTRO=${ROS_DISTRO} +RUN test -n "$ROS_DISTRO" || (echo "missing build-arg: ROS_DISTRO" && false) +RUN apt-get update && \ + apt-get install -y curl gnupg && \ + apt-key adv --keyserver hkp://keyserver.ubuntu.com:80 --recv-keys C1CF6E31E6BADE8868B172B4F42ED6FBAB17C654 && \ + echo "deb http://packages.ros.org/ros/ubuntu focal main" > /etc/apt/sources.list.d/ros1-latest.list && \ + curl -sSL https://raw.githubusercontent.com/ros/rosdistro/master/ros.key -o /usr/share/keyrings/ros-archive-keyring.gpg && \ + echo "deb [arch=$(dpkg --print-architecture) signed-by=/usr/share/keyrings/ros-archive-keyring.gpg] http://packages.ros.org/ros2/ubuntu $(. /etc/os-release && echo $UBUNTU_CODENAME) main" | tee /etc/apt/sources.list.d/ros2.list > /dev/null && \ + rm -rf /var/lib/apt/lists/* + +# copy contents of files-folder into image +ADD docker/files* /docker-ros/files/ + +# install essential ROS CLI tools +RUN apt-get update && \ + apt-get install -y \ + build-essential \ + gosu \ + && source /opt/ros/$ROS_DISTRO/setup.bash && \ + if [ "$ROS_VERSION" == "1" ]; then \ + apt-get install -y \ + python3-catkin-tools ; \ + elif [ "$ROS_VERSION" == "2" ]; then \ + apt-get install -y \ + python3-colcon-common-extensions ; \ + fi \ + && rm -rf /var/lib/apt/lists/* + +# copy install script from dependencies stage +COPY --from=dependencies $WORKSPACE/.install-dependencies.sh $WORKSPACE/.install-dependencies.sh + +# install dependencies +RUN apt-get update && \ + $WORKSPACE/.install-dependencies.sh && \ + rm -rf /var/lib/apt/lists/* + +# source ROS +RUN echo "source /opt/ros/$ROS_DISTRO/setup.bash" >> ~/.bashrc + +# set entrypoint +COPY docker/docker-ros/entrypoint.sh / +ENTRYPOINT ["/entrypoint.sh"] + +############ dev ############################################################### +FROM dependencies-install as dev + +# copy contents of repository from dependencies stage +COPY --from=dependencies $WORKSPACE/src $WORKSPACE/src + +CMD ["bash"] + +############ build ############################################################# +FROM dev as build + +# build ROS workspace +RUN if [ -x "$(command -v colcon)" ]; then \ + source /opt/ros/${ROS_DISTRO}/setup.bash && \ + colcon build --cmake-args -DCMAKE_BUILD_TYPE=Release ; \ + elif [ -x "$(command -v catkin)" ]; then \ + catkin config --install --extend /opt/ros/${ROS_DISTRO} && \ + catkin build -DCMAKE_BUILD_TYPE=Release --force-color --no-status --summarize ; \ + fi + +############ run ############################################################### +FROM dependencies-install as run + +# copy ROS install space from build stage +COPY --from=build $WORKSPACE/install install +RUN ldconfig +RUN echo "[[ -f $WORKSPACE/devel/setup.bash ]] && source $WORKSPACE/devel/setup.bash" >> ~/.bashrc && \ + echo "[[ -f $WORKSPACE/install/setup.bash ]] && source $WORKSPACE/install/setup.bash" >> ~/.bashrc + +# setup command +ARG COMMAND +ENV DEFAULT_CMD=${COMMAND} +CMD ${DEFAULT_CMD} diff --git a/action.yml b/action.yml index 0011139..f4ca514 100644 --- a/action.yml +++ b/action.yml @@ -1,16 +1,24 @@ # action.yml name: 'Hello World' -description: 'Greet someone and record the time' +description: 'Greet someone' inputs: who-to-greet: # id of input description: 'Who to greet' required: true default: 'World' outputs: - time: # id of output - description: 'The time we greeted you' + random-number: + description: "Random number" + value: ${{ steps.random-number-generator.outputs.random-number }} runs: - using: 'docker' - image: 'Dockerfile' - args: - - ${{ inputs.who-to-greet }} \ No newline at end of file + using: "composite" + steps: + - run: echo Hello ${{ inputs.who-to-greet }}. + shell: bash + - id: random-number-generator + run: echo "random-number=$(echo $RANDOM)" >> $GITHUB_OUTPUT + shell: bash + - run: echo "${{ github.action_path }}" >> $GITHUB_PATH + shell: bash + - run: echo "Goodbye" + shell: bash \ No newline at end of file diff --git a/entrypoint.sh b/entrypoint.sh index 6184045..5771f19 100755 --- a/entrypoint.sh +++ b/entrypoint.sh @@ -1,6 +1,29 @@ -#!/bin/sh -l +#!/bin/bash +set -e -echo "Hello $1" -echo "REPO $GITHUB_REPOSITORY" -time=$(date) -echo "time=$time" >> $GITHUB_OUTPUT \ No newline at end of file +# source ROS workspace +source /opt/ros/$ROS_DISTRO/setup.bash +[[ -f $WORKSPACE/devel/setup.bash ]] && source $WORKSPACE/devel/setup.bash +[[ -f $WORKSPACE/install/setup.bash ]] && source $WORKSPACE/install/setup.bash + +# exec as dockeruser with configured UID/GID +if [[ $DOCKER_UID && $DOCKER_GID ]]; then + groupadd -g $DOCKER_GID $DOCKER_USER + useradd -s /bin/bash \ + -u $DOCKER_UID \ + -g $DOCKER_USER \ + --create-home \ + --home-dir /home/$DOCKER_USER \ + --groups sudo,video \ + --password "$(openssl passwd -1 $DOCKER_USER)" \ + $DOCKER_USER && \ + touch /home/$DOCKER_USER/.sudo_as_admin_successful + chown -R $DOCKER_USER:$DOCKER_USER $WORKSPACE + ln -s $WORKSPACE /home/$DOCKER_USER/ws + cd /home/$DOCKER_USER/ws + cp /root/.bashrc /home/$DOCKER_USER + chown $DOCKER_USER:$DOCKER_USER /home/$DOCKER_USER/.bashrc + exec gosu $DOCKER_USER "$@" +else + exec "$@" +fi From 2781246c5bab6731c26524d412a96ec6300d81ba Mon Sep 17 00:00:00 2001 From: Jean-Pierre Busch Date: Wed, 24 May 2023 18:02:59 +0200 Subject: [PATCH 008/159] trigger by api --- .github/workflows/main.yml | 59 +++++++++++++++++++------------------- 1 file changed, 29 insertions(+), 30 deletions(-) diff --git a/.github/workflows/main.yml b/.github/workflows/main.yml index 932382a..371b946 100644 --- a/.github/workflows/main.yml +++ b/.github/workflows/main.yml @@ -5,34 +5,33 @@ jobs: name: Trigger docker-ros-ci workflow runs-on: ubuntu-latest steps: - - name: Trigger docker-ros-ci using repository-dispatch - id: repository-dispatch - uses: peter-evans/repository-dispatch@v2 - with: - token: ${{ secrets.PAT }} # Personal Access Token with appropriate permissions - repository: ika-rwth-aachen/docker-ros-ci - ref: feature/github-workflow - event-type: my-event - #client-payload: '{"ref": "feature/github-workflow"}' - # - name: Trigger by API - # run: | - # curl -X POST -H "Authorization: Bearer ${{ secrets.PAT }}" -H "Accept: application/vnd.github.v3+json" -d '{"ref":"feature/github-workflow"}' "https://api.github.com/repos/ika-rwth-aachen/docker-ros-ci/actions/workflows/main.yml/dispatches" - watch_workflow: - name: Watch docker-ros-ci workflow run - runs-on: ubuntu-latest - needs: trigger_workflow - steps: - - name: Check Pipeline Status - id: check_status + # - name: Trigger docker-ros-ci using repository-dispatch + # id: repository-dispatch + # uses: peter-evans/repository-dispatch@v2 + # with: + # token: ${{ secrets.PAT }} # Personal Access Token with appropriate permissions + # repository: ika-rwth-aachen/docker-ros-ci + # event-type: my-event + # client-payload: '{"ref": "feature/github-workflow"}' + - name: Trigger by API run: | - echo TEST ${{ needs.trigger_pipeline.outputs.dispatch.outputs.run_id }} - while true; do - sleep 30 - PIPELINE_STATUS=$(curl --silent --header "Authorization: Bearer ${{ secrets.PAT }}" "https://api.github.com/repos/owner/other-repository/actions/runs/${{ needs.trigger_pipeline.outputs.dispatch.outputs.run_id }}" | jq -r '.status') - echo "Pipeline status: $PIPELINE_STATUS" - if [[ $PIPELINE_STATUS == "completed" ]]; then - break - elif [[ $PIPELINE_STATUS == "failure" || $PIPELINE_STATUS == "cancelled" ]]; then - exit 1 - fi - done \ No newline at end of file + curl -X POST -H "Authorization: Bearer ${{ secrets.PAT }}" -H "Accept: application/vnd.github.v3+json" -d '{"ref":"feature/github-workflow"}' "https://api.github.com/repos/ika-rwth-aachen/docker-ros-ci/actions/workflows/main.yml/dispatches" +# watch_workflow: +# name: Watch docker-ros-ci workflow run +# runs-on: ubuntu-latest +# needs: trigger_workflow +# steps: +# - name: Check Pipeline Status +# id: check_status +# run: | +# echo TEST ${{ needs.trigger_pipeline.outputs.dispatch.outputs.run_id }} +# while true; do +# sleep 30 +# PIPELINE_STATUS=$(curl --silent --header "Authorization: Bearer ${{ secrets.PAT }}" "https://api.github.com/repos/owner/other-repository/actions/runs/${{ needs.trigger_pipeline.outputs.dispatch.outputs.run_id }}" | jq -r '.status') +# echo "Pipeline status: $PIPELINE_STATUS" +# if [[ $PIPELINE_STATUS == "completed" ]]; then +# break +# elif [[ $PIPELINE_STATUS == "failure" || $PIPELINE_STATUS == "cancelled" ]]; then +# exit 1 +# fi +# done \ No newline at end of file From a129f4267bc91c408ab53e592434a39730a77422 Mon Sep 17 00:00:00 2001 From: Jean-Pierre Busch Date: Wed, 24 May 2023 18:22:04 +0200 Subject: [PATCH 009/159] test docker --- action.yml | 26 ++++++++++++++------------ 1 file changed, 14 insertions(+), 12 deletions(-) diff --git a/action.yml b/action.yml index f4ca514..e47a8aa 100644 --- a/action.yml +++ b/action.yml @@ -2,10 +2,14 @@ name: 'Hello World' description: 'Greet someone' inputs: - who-to-greet: # id of input - description: 'Who to greet' - required: true - default: 'World' + docker-compose-file: + description: 'docker-compose-file' + required: false + default: 'docker-compose.yml' + docker-compose-dir: + description: 'docker-compose-dir' + required: false + default: 'docker' outputs: random-number: description: "Random number" @@ -13,12 +17,10 @@ outputs: runs: using: "composite" steps: - - run: echo Hello ${{ inputs.who-to-greet }}. - shell: bash - - id: random-number-generator - run: echo "random-number=$(echo $RANDOM)" >> $GITHUB_OUTPUT - shell: bash - - run: echo "${{ github.action_path }}" >> $GITHUB_PATH - shell: bash - - run: echo "Goodbye" + - name: checkout code + uses: actions/checkout@v3 + - name: setup docker buildx + uses: docker/setup-buildx-action@v2 + - name: docker build + run: docker compose -f ${{ inputs.docker-compose-file }}/${{ inputs.docker-compose-file }} build ${TARGET} shell: bash \ No newline at end of file From 4a699cb77898adaa90c318219a7771902e8bda7b Mon Sep 17 00:00:00 2001 From: Jean-Pierre Busch Date: Wed, 24 May 2023 18:24:30 +0200 Subject: [PATCH 010/159] fix --- action.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/action.yml b/action.yml index e47a8aa..33555f0 100644 --- a/action.yml +++ b/action.yml @@ -22,5 +22,5 @@ runs: - name: setup docker buildx uses: docker/setup-buildx-action@v2 - name: docker build - run: docker compose -f ${{ inputs.docker-compose-file }}/${{ inputs.docker-compose-file }} build ${TARGET} + run: docker compose -f ${{ inputs.docker-compose-dir }}/${{ inputs.docker-compose-file }} build ${TARGET} shell: bash \ No newline at end of file From 2687174a282e99a9c8ef9fdaba8caefa0b4d8616 Mon Sep 17 00:00:00 2001 From: Jean-Pierre Busch Date: Wed, 24 May 2023 18:26:20 +0200 Subject: [PATCH 011/159] fix file --- action.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/action.yml b/action.yml index 33555f0..ef43de4 100644 --- a/action.yml +++ b/action.yml @@ -5,7 +5,7 @@ inputs: docker-compose-file: description: 'docker-compose-file' required: false - default: 'docker-compose.yml' + default: 'docker-compose.yaml' docker-compose-dir: description: 'docker-compose-dir' required: false From 3587368af26379122e832bd7bf9bfe3367870a59 Mon Sep 17 00:00:00 2001 From: Jean-Pierre Busch Date: Wed, 24 May 2023 18:37:07 +0200 Subject: [PATCH 012/159] clone docker-ros --- action.yml | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/action.yml b/action.yml index ef43de4..8bd9d5f 100644 --- a/action.yml +++ b/action.yml @@ -21,6 +21,12 @@ runs: uses: actions/checkout@v3 - name: setup docker buildx uses: docker/setup-buildx-action@v2 + - name: checkout docker-ros + uses: actions/checkout@v3 + with: + repository: ika-rwth-aachen/docker-ros + token: ${{ secrets.PAT }} + path: ${{ inputs.docker-compose-dir }}/docker-ros - name: docker build run: docker compose -f ${{ inputs.docker-compose-dir }}/${{ inputs.docker-compose-file }} build ${TARGET} shell: bash \ No newline at end of file From 34c87be310ee0d58b41352a8b1f28b8ad4a597a3 Mon Sep 17 00:00:00 2001 From: Jean-Pierre Busch Date: Wed, 24 May 2023 18:42:13 +0200 Subject: [PATCH 013/159] use token for cloning docker-ros --- action.yml | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/action.yml b/action.yml index 8bd9d5f..dc35c14 100644 --- a/action.yml +++ b/action.yml @@ -10,6 +10,10 @@ inputs: description: 'docker-compose-dir' required: false default: 'docker' + token: + description: 'access token for cloning docker-ros' + required: true + default: '' outputs: random-number: description: "Random number" @@ -25,7 +29,7 @@ runs: uses: actions/checkout@v3 with: repository: ika-rwth-aachen/docker-ros - token: ${{ secrets.PAT }} + token: ${{ inputs.token }} path: ${{ inputs.docker-compose-dir }}/docker-ros - name: docker build run: docker compose -f ${{ inputs.docker-compose-dir }}/${{ inputs.docker-compose-file }} build ${TARGET} From eb6673d4747ca089c53d6f6ff7ad92e7186d8195 Mon Sep 17 00:00:00 2001 From: Lennart Reiher Date: Thu, 25 May 2023 11:48:25 +0200 Subject: [PATCH 014/159] add first version of building bash script --- build.sh | 49 +++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 49 insertions(+) create mode 100755 build.sh diff --git a/build.sh b/build.sh new file mode 100755 index 0000000..9291aeb --- /dev/null +++ b/build.sh @@ -0,0 +1,49 @@ +#!/bin/bash + +set -e + +# load environment variables +_BASE_IMAGE="${BASE_IMAGE}" +_COMMAND="${COMMAND}" +_DEV_IMAGE="${DEV_IMAGE}" +_RUN_IMAGE="${RUN_IMAGE}" +_TARGET="${TARGET}" + +# load (unset) variables from .env file +source .env +[[ -z "${_BASE_IMAGE}" ]] && _BASE_IMAGE="${BASE_IMAGE}" +[[ -z "${_COMMAND}" ]] && _COMMAND="${COMMAND}" +[[ -z "${_DEV_IMAGE}" ]] && _DEV_IMAGE="${DEV_IMAGE}" +[[ -z "${_RUN_IMAGE}" ]] && _RUN_IMAGE="${RUN_IMAGE}" +[[ -z "${_TARGET}" ]] && _TARGET="${TARGET}" + +# check for required environment variables +[[ -z "${_BASE_IMAGE}" ]] && echo "Environment variable 'BASE_IMAGE' is required" && exit 1 +[[ -z "${_COMMAND}" ]] && echo "Environment variable 'COMMAND' is required" && exit 1 + +# evaluate which targets to build +if [[ -z "${_TARGET}" ]]; then + [[ -z "${_DEV_IMAGE}" && -z "${_RUN_IMAGE}" ]] && echo "One of environment variables 'DEV_IMAGE' or 'RUN_IMAGE' is required" && exit 1 + [[ -n "${_DEV_IMAGE}" && -z "${_RUN_IMAGE}" ]] && _TAGS=( "${_DEV_IMAGE}" ) && _TARGETS=( dev ) + [[ -z "${_DEV_IMAGE}" && -n "${_RUN_IMAGE}" ]] && _TAGS=( "${_RUN_IMAGE}" ) && _TARGETS=( run ) + [[ -n "${_DEV_IMAGE}" && -n "${_RUN_IMAGE}" ]] && _TAGS=( "${_DEV_IMAGE}" "${_RUN_IMAGE}" ) && _TARGETS=( dev run ) +else + [[ "${_TARGET}" == "dev" ]] && _TAGS=( "${_DEV_IMAGE}" ) && [[ -z "${_DEV_IMAGE}" ]] && echo "Environment variable 'DEV_IMAGE' is required" && exit 1 + [[ "${_TARGET}" == "run" ]] && _TAGS=( "${_RUN_IMAGE}" ) && [[ -z "${_RUN_IMAGE}" ]] && echo "Environment variable 'RUN_IMAGE' is required" && exit 1 + _TARGETS=( "${_TARGET}" ) +fi + +# build image(s) +for (( i=0; i<${#_TARGETS[*]}; ++i)); do + echo "Building stage '${_TARGETS[$i]}' as '${_TAGS[$i]}' ..." + docker build \ + --file docker-ros/Dockerfile \ + --target "${_TARGETS[$i]}" \ + --tag "${_TAGS[$i]}" \ + --build-arg BASE_IMAGE="${_BASE_IMAGE}" \ + --build-arg COMMAND="${_COMMAND}" \ + .. +done +for (( i=0; i<${#_TARGETS[*]}; ++i)); do + echo "Successfully built stage '${_TARGETS[$i]}' as '${_TAGS[$i]}'" +done From e006e92423112e48a9eda599d1ad0369c107c1d8 Mon Sep 17 00:00:00 2001 From: Lennart Reiher Date: Thu, 25 May 2023 11:50:25 +0200 Subject: [PATCH 015/159] add GIT_HTTPS build args to build script --- build.sh | 16 +++++++++++----- 1 file changed, 11 insertions(+), 5 deletions(-) diff --git a/build.sh b/build.sh index 9291aeb..d153d35 100755 --- a/build.sh +++ b/build.sh @@ -6,16 +6,20 @@ set -e _BASE_IMAGE="${BASE_IMAGE}" _COMMAND="${COMMAND}" _DEV_IMAGE="${DEV_IMAGE}" +_GIT_HTTPS_PASSWORD="${GIT_HTTPS_PASSWORD}" +_GIT_HTTPS_USER="${GIT_HTTPS_USER}" _RUN_IMAGE="${RUN_IMAGE}" _TARGET="${TARGET}" # load (unset) variables from .env file source .env -[[ -z "${_BASE_IMAGE}" ]] && _BASE_IMAGE="${BASE_IMAGE}" -[[ -z "${_COMMAND}" ]] && _COMMAND="${COMMAND}" -[[ -z "${_DEV_IMAGE}" ]] && _DEV_IMAGE="${DEV_IMAGE}" -[[ -z "${_RUN_IMAGE}" ]] && _RUN_IMAGE="${RUN_IMAGE}" -[[ -z "${_TARGET}" ]] && _TARGET="${TARGET}" +[[ -z "${_BASE_IMAGE}" ]] && _BASE_IMAGE="${BASE_IMAGE}" +[[ -z "${_COMMAND}" ]] && _COMMAND="${COMMAND}" +[[ -z "${_DEV_IMAGE}" ]] && _DEV_IMAGE="${DEV_IMAGE}" +[[ -z "${_GIT_HTTPS_PASSWORD}" ]] && _TARGET="${GIT_HTTPS_PASSWORD}" +[[ -z "${_GIT_HTTPS_USER}" ]] && _TARGET="${GIT_HTTPS_USER}" +[[ -z "${_RUN_IMAGE}" ]] && _RUN_IMAGE="${RUN_IMAGE}" +[[ -z "${_TARGET}" ]] && _TARGET="${TARGET}" # check for required environment variables [[ -z "${_BASE_IMAGE}" ]] && echo "Environment variable 'BASE_IMAGE' is required" && exit 1 @@ -42,6 +46,8 @@ for (( i=0; i<${#_TARGETS[*]}; ++i)); do --tag "${_TAGS[$i]}" \ --build-arg BASE_IMAGE="${_BASE_IMAGE}" \ --build-arg COMMAND="${_COMMAND}" \ + --build-arg GIT_HTTPS_PASSWORD="${_GIT_HTTPS_PASSWORD}" \ + --build-arg GIT_HTTPS_USER="${_GIT_HTTPS_USER}" \ .. done for (( i=0; i<${#_TARGETS[*]}; ++i)); do From 29d6d3eb558bea6fb69089edc7885f40a8610bdd Mon Sep 17 00:00:00 2001 From: Lennart Reiher Date: Thu, 25 May 2023 11:56:46 +0200 Subject: [PATCH 016/159] add option to set platform in build script --- build.sh | 10 +++++++--- 1 file changed, 7 insertions(+), 3 deletions(-) diff --git a/build.sh b/build.sh index d153d35..d5c735c 100755 --- a/build.sh +++ b/build.sh @@ -8,6 +8,7 @@ _COMMAND="${COMMAND}" _DEV_IMAGE="${DEV_IMAGE}" _GIT_HTTPS_PASSWORD="${GIT_HTTPS_PASSWORD}" _GIT_HTTPS_USER="${GIT_HTTPS_USER}" +_PLATFORM="${PLATFORM}" _RUN_IMAGE="${RUN_IMAGE}" _TARGET="${TARGET}" @@ -18,12 +19,14 @@ source .env [[ -z "${_DEV_IMAGE}" ]] && _DEV_IMAGE="${DEV_IMAGE}" [[ -z "${_GIT_HTTPS_PASSWORD}" ]] && _TARGET="${GIT_HTTPS_PASSWORD}" [[ -z "${_GIT_HTTPS_USER}" ]] && _TARGET="${GIT_HTTPS_USER}" +[[ -z "${_PLATFORM}" ]] && _RUN_IMAGE="${PLATFORM}" [[ -z "${_RUN_IMAGE}" ]] && _RUN_IMAGE="${RUN_IMAGE}" [[ -z "${_TARGET}" ]] && _TARGET="${TARGET}" -# check for required environment variables +# check for required environment variables or set defaults [[ -z "${_BASE_IMAGE}" ]] && echo "Environment variable 'BASE_IMAGE' is required" && exit 1 [[ -z "${_COMMAND}" ]] && echo "Environment variable 'COMMAND' is required" && exit 1 +_PLATFORM="${_PLATFORM:-$(dpkg --print-architecture)}" # evaluate which targets to build if [[ -z "${_TARGET}" ]]; then @@ -39,10 +42,11 @@ fi # build image(s) for (( i=0; i<${#_TARGETS[*]}; ++i)); do - echo "Building stage '${_TARGETS[$i]}' as '${_TAGS[$i]}' ..." + echo "Building stage '${_TARGETS[$i]}' for platform '${_PLATFORM}' as '${_TAGS[$i]}' ..." docker build \ --file docker-ros/Dockerfile \ --target "${_TARGETS[$i]}" \ + --platform "${_PLATFORM}" \ --tag "${_TAGS[$i]}" \ --build-arg BASE_IMAGE="${_BASE_IMAGE}" \ --build-arg COMMAND="${_COMMAND}" \ @@ -51,5 +55,5 @@ for (( i=0; i<${#_TARGETS[*]}; ++i)); do .. done for (( i=0; i<${#_TARGETS[*]}; ++i)); do - echo "Successfully built stage '${_TARGETS[$i]}' as '${_TAGS[$i]}'" + echo "Successfully built stage '${_TARGETS[$i]}' for platform ${_PLATFORM} as '${_TAGS[$i]}'" done From 51176a0d6f3ac1eda91b866ac58a0855ba154b3e Mon Sep 17 00:00:00 2001 From: Lennart Reiher Date: Thu, 25 May 2023 12:31:41 +0200 Subject: [PATCH 017/159] support cache-from and cache-to in build script --- build.sh | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/build.sh b/build.sh index d5c735c..3d21540 100755 --- a/build.sh +++ b/build.sh @@ -4,6 +4,8 @@ set -e # load environment variables _BASE_IMAGE="${BASE_IMAGE}" +_CACHE_FROM="${CACHE_FROM}" +_CACHE_TO="${CACHE_TO}" _COMMAND="${COMMAND}" _DEV_IMAGE="${DEV_IMAGE}" _GIT_HTTPS_PASSWORD="${GIT_HTTPS_PASSWORD}" @@ -15,6 +17,8 @@ _TARGET="${TARGET}" # load (unset) variables from .env file source .env [[ -z "${_BASE_IMAGE}" ]] && _BASE_IMAGE="${BASE_IMAGE}" +[[ -z "${_CACHE_FROM}" ]] && _CACHE_FROM="${CACHE_FROM}" +[[ -z "${_CACHE_TO}" ]] && _CACHE_TO="${CACHE_TO}" [[ -z "${_COMMAND}" ]] && _COMMAND="${COMMAND}" [[ -z "${_DEV_IMAGE}" ]] && _DEV_IMAGE="${DEV_IMAGE}" [[ -z "${_GIT_HTTPS_PASSWORD}" ]] && _TARGET="${GIT_HTTPS_PASSWORD}" @@ -48,6 +52,8 @@ for (( i=0; i<${#_TARGETS[*]}; ++i)); do --target "${_TARGETS[$i]}" \ --platform "${_PLATFORM}" \ --tag "${_TAGS[$i]}" \ + $(if [[ -n "${_CACHE_FROM}" ]]; then echo "--cache-from ${_CACHE_FROM}"; fi) \ + $(if [[ -n "${_CACHE_TO}" ]]; then echo "--cache-to ${_CACHE_TO}"; fi) \ --build-arg BASE_IMAGE="${_BASE_IMAGE}" \ --build-arg COMMAND="${_COMMAND}" \ --build-arg GIT_HTTPS_PASSWORD="${_GIT_HTTPS_PASSWORD}" \ From 4a94b3272350a8c6db3e7d3281e4923130b7a4cc Mon Sep 17 00:00:00 2001 From: Lennart Reiher Date: Thu, 25 May 2023 12:36:26 +0200 Subject: [PATCH 018/159] switch gitlab ci to bash script --- templates/.gitlab-ci.template.yml | 17 ++++++----------- templates/docker-compose.template.yml | 27 --------------------------- 2 files changed, 6 insertions(+), 38 deletions(-) delete mode 100644 templates/docker-compose.template.yml diff --git a/templates/.gitlab-ci.template.yml b/templates/.gitlab-ci.template.yml index f9d94c5..68fce15 100644 --- a/templates/.gitlab-ci.template.yml +++ b/templates/.gitlab-ci.template.yml @@ -26,8 +26,7 @@ variables: PUSH_AS_LATEST: 'false' # ----- DOCKER_ROS_GIT_REF: main - DOCKER_COMPOSE_DIR: docker - DOCKER_COMPOSE_FILE: docker-compose.yml + DOCKER_DIR: docker ROS_DIR: . DISABLE_ARCH_AMD64: 'false' DISABLE_ARCH_ARM64: 'false' @@ -58,10 +57,10 @@ default: - amd64 before_script: - |- - if [[ ! -d $DOCKER_COMPOSE_DIR/docker-ros ]]; then + if [[ ! -d $DOCKER_DIR/docker-ros ]]; then git config --global url.${CI_SERVER_PROTOCOL}://gitlab-ci-token:${CI_JOB_TOKEN}@${CI_SERVER_HOST}:${CI_SERVER_PORT}.insteadOf ${CI_SERVER_URL} - git clone --depth=1 https://gitlab.ika.rwth-aachen.de/fb-fi/ops/docker-ros.git $DOCKER_COMPOSE_DIR/docker-ros - cd $DOCKER_COMPOSE_DIR/docker-ros + git clone --depth=1 https://gitlab.ika.rwth-aachen.de/fb-fi/ops/docker-ros.git $DOCKER_DIR/docker-ros + cd $DOCKER_DIR/docker-ros git fetch origin $DOCKER_ROS_GIT_REF git checkout FETCH_HEAD cd - @@ -69,16 +68,12 @@ default: - docker login -u $CI_REGISTRY_USER -p $CI_REGISTRY_PASSWORD $CI_REGISTRY - docker context create buildx-context - docker buildx create --use buildx-context - - cd $DOCKER_COMPOSE_DIR - - ln $(echo "${DOCKER_COMPOSE_FILE%.*}").yml ${DOCKER_COMPOSE_FILE} 2> /dev/null || true - - ln $(echo "${DOCKER_COMPOSE_FILE%.*}").yaml ${DOCKER_COMPOSE_FILE} 2> /dev/null || true - - 'sed -i "/\ image:/a\ platform: $PLATFORM" $DOCKER_COMPOSE_FILE' - - 'sed -i "/\ context:/a\ cache_from: [$IMG_CACHE]\n\ cache_to: [type=inline]" $DOCKER_COMPOSE_FILE' + - cd $DOCKER_DIR .build: script: - - docker compose -f $DOCKER_COMPOSE_FILE build ${TARGET} + - ./docker-ros/build.sh - docker tag ${IMG_TARGET} ${IMG} - docker push ${IMG} diff --git a/templates/docker-compose.template.yml b/templates/docker-compose.template.yml deleted file mode 100644 index 5e3d85e..0000000 --- a/templates/docker-compose.template.yml +++ /dev/null @@ -1,27 +0,0 @@ -x-base-image: &base-image BASE_IMAGE # e.g. gitlab.ika.rwth-aachen.de:5050/fb-fi/ops/docker-base/ros2:latest -x-dev-image: &dev-image DEV_IMAGE # e.g. gitlab.ika.rwth-aachen.de:5050/fb-fi/ops/hello_world:latest-dev -x-run-image: &run-image RUN_IMAGE # e.g. gitlab.ika.rwth-aachen.de:5050/fb-fi/ops/hello_world:latest -x-command: &command COMMAND # e.g. ros2 topic pub "/ping" "std_msgs/msg/String" "{data: Hello World}" - -# ============================================================================== - -x-build: &build - dockerfile: ./docker/docker-ros/Dockerfile - context: ../ - args: - BASE_IMAGE: *base-image - COMMAND: *command - GIT_HTTPS_USER: $GIT_HTTPS_USER - GIT_HTTPS_PASSWORD: $GIT_HTTPS_PASSWORD - -services: - dev: - image: *dev-image - build: - target: dev - <<: *build - run: - image: *run-image - build: - target: run - <<: *build From ce0447e13a0513d841600188b03ff1f6265c1875 Mon Sep 17 00:00:00 2001 From: Lennart Reiher Date: Thu, 25 May 2023 12:37:07 +0200 Subject: [PATCH 019/159] switch to docker-ros-ci branch --- .gitlab-ci.yml | 11 +---------- 1 file changed, 1 insertion(+), 10 deletions(-) diff --git a/.gitlab-ci.yml b/.gitlab-ci.yml index 23b51c5..4894639 100644 --- a/.gitlab-ci.yml +++ b/.gitlab-ci.yml @@ -19,12 +19,7 @@ default: Trigger ROS1: extends: .trigger variables: - DOCKER_ROS_CI_GIT_REF: main - -Trigger ROS2: - extends: .trigger - variables: - DOCKER_ROS_CI_GIT_REF: ros2 + DOCKER_ROS_CI_GIT_REF: test/docker-ros-refactor .watch: @@ -48,7 +43,3 @@ Trigger ROS2: Watch ROS1: extends: .watch needs: [Trigger ROS1] - -Watch ROS2: - extends: .watch - needs: [Trigger ROS2] From 3690f234bd81725ef6ebc6b8d91fcb28ded6de88 Mon Sep 17 00:00:00 2001 From: Lennart Reiher Date: Thu, 25 May 2023 12:41:29 +0200 Subject: [PATCH 020/159] switch to docker buildx build to explicitly use buildkit --- build.sh | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/build.sh b/build.sh index 3d21540..dcdfbe5 100755 --- a/build.sh +++ b/build.sh @@ -47,7 +47,7 @@ fi # build image(s) for (( i=0; i<${#_TARGETS[*]}; ++i)); do echo "Building stage '${_TARGETS[$i]}' for platform '${_PLATFORM}' as '${_TAGS[$i]}' ..." - docker build \ + docker buildx build \ --file docker-ros/Dockerfile \ --target "${_TARGETS[$i]}" \ --platform "${_PLATFORM}" \ From 4b2f480dba901dea9ee95b80c4c4a524c17cf488 Mon Sep 17 00:00:00 2001 From: Lennart Reiher Date: Thu, 25 May 2023 12:42:51 +0200 Subject: [PATCH 021/159] install bash in ci image to run build script --- templates/.gitlab-ci.template.yml | 1 + 1 file changed, 1 insertion(+) diff --git a/templates/.gitlab-ci.template.yml b/templates/.gitlab-ci.template.yml index 68fce15..2804204 100644 --- a/templates/.gitlab-ci.template.yml +++ b/templates/.gitlab-ci.template.yml @@ -56,6 +56,7 @@ default: - privileged - amd64 before_script: + - apk add bash - |- if [[ ! -d $DOCKER_DIR/docker-ros ]]; then git config --global url.${CI_SERVER_PROTOCOL}://gitlab-ci-token:${CI_JOB_TOKEN}@${CI_SERVER_HOST}:${CI_SERVER_PORT}.insteadOf ${CI_SERVER_URL} From b19f09e2943638d3e028c7a7238aee3794fce95d Mon Sep 17 00:00:00 2001 From: Jean-Pierre Busch Date: Thu, 25 May 2023 14:35:58 +0200 Subject: [PATCH 022/159] test action --- .github/actions/docker-build.yml | 30 ++++++++++++++++++++++++++++++ action.yml | 28 +++++++++++++++++----------- 2 files changed, 47 insertions(+), 11 deletions(-) create mode 100644 .github/actions/docker-build.yml diff --git a/.github/actions/docker-build.yml b/.github/actions/docker-build.yml new file mode 100644 index 0000000..cfd4c56 --- /dev/null +++ b/.github/actions/docker-build.yml @@ -0,0 +1,30 @@ +name: 'Docker build' +description: 'Docker build action' + +inputs: + platform: + description: 'target platform (e.g. amd64 / arm64)' + required: true + target: + description: 'docker target stage' + required: true + target-image: + description: 'image name in compose file' + required: true + image-name: + description: 'image name' + required: true + image-cache: + description: 'image to cache from' + required: false + default: ${{ inputs.image-name }} +runs: + using: "composite" + steps: + - name: docker build + run: docker compose -f $DOCKER_COMPOSE_DIR/$DOCKER_COMPOSE_FILE build ${{ inputs.target }} + shell: bash + - name: docker tag + run: docker tag ${{ inputs.target-image }} ${{ inputs.image-name }} + - name: docker push + run: docker push ${{ inputs.image-name }} \ No newline at end of file diff --git a/action.yml b/action.yml index dc35c14..922fe63 100644 --- a/action.yml +++ b/action.yml @@ -1,15 +1,10 @@ # action.yml name: 'Hello World' description: 'Greet someone' +env: + DOCKER_COMPOSE_DIR: docker + DOCKER_COMPOSE_FILE: docker-compose.yml inputs: - docker-compose-file: - description: 'docker-compose-file' - required: false - default: 'docker-compose.yaml' - docker-compose-dir: - description: 'docker-compose-dir' - required: false - default: 'docker' token: description: 'access token for cloning docker-ros' required: true @@ -31,6 +26,17 @@ runs: repository: ika-rwth-aachen/docker-ros token: ${{ inputs.token }} path: ${{ inputs.docker-compose-dir }}/docker-ros - - name: docker build - run: docker compose -f ${{ inputs.docker-compose-dir }}/${{ inputs.docker-compose-file }} build ${TARGET} - shell: bash \ No newline at end of file + - name: docker build dev + uses: ./.github/actions/docker-build.yml + with: + platform: amd64 + target: dev + target-image: ghcr.io/$GIHUB_REPOSITORY:latest-dev + image-name: ghcr.io/${GIHUB_REPOSITORY}_ci-amd64-dev + - name: docker build run + uses: ./.github/actions/docker-build.yml + with: + platform: amd64 + target: run + target-image: ghcr.io/$GIHUB_REPOSITORY:latest + image-name: ghcr.io/${GIHUB_REPOSITORY}_ci-amd64 \ No newline at end of file From 4756561876eadf65933f0343419fa24717f46db4 Mon Sep 17 00:00:00 2001 From: Jean-Pierre Busch Date: Thu, 25 May 2023 14:38:31 +0200 Subject: [PATCH 023/159] fix action --- action.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/action.yml b/action.yml index 922fe63..477d6d9 100644 --- a/action.yml +++ b/action.yml @@ -25,7 +25,7 @@ runs: with: repository: ika-rwth-aachen/docker-ros token: ${{ inputs.token }} - path: ${{ inputs.docker-compose-dir }}/docker-ros + path: $DOCKER_COMPOSE_DIR/docker-ros - name: docker build dev uses: ./.github/actions/docker-build.yml with: From 37c1e397ee2dc7783f219e5bb1773199265566e2 Mon Sep 17 00:00:00 2001 From: Jean-Pierre Busch Date: Thu, 25 May 2023 14:40:56 +0200 Subject: [PATCH 024/159] test checkout for subaction --- .github/actions/docker-build.yml | 2 ++ 1 file changed, 2 insertions(+) diff --git a/.github/actions/docker-build.yml b/.github/actions/docker-build.yml index cfd4c56..e995992 100644 --- a/.github/actions/docker-build.yml +++ b/.github/actions/docker-build.yml @@ -21,6 +21,8 @@ inputs: runs: using: "composite" steps: + - name: checkout code + uses: actions/checkout@v3 - name: docker build run: docker compose -f $DOCKER_COMPOSE_DIR/$DOCKER_COMPOSE_FILE build ${{ inputs.target }} shell: bash From e6ddbe4d9fc00bad081b983b3d287d60692ba55c Mon Sep 17 00:00:00 2001 From: Lennart Reiher Date: Thu, 25 May 2023 14:42:29 +0200 Subject: [PATCH 025/159] load buildx image to docker images --- build.sh | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/build.sh b/build.sh index dcdfbe5..9a97fbd 100755 --- a/build.sh +++ b/build.sh @@ -51,6 +51,7 @@ for (( i=0; i<${#_TARGETS[*]}; ++i)); do --file docker-ros/Dockerfile \ --target "${_TARGETS[$i]}" \ --platform "${_PLATFORM}" \ + --load \ --tag "${_TAGS[$i]}" \ $(if [[ -n "${_CACHE_FROM}" ]]; then echo "--cache-from ${_CACHE_FROM}"; fi) \ $(if [[ -n "${_CACHE_TO}" ]]; then echo "--cache-to ${_CACHE_TO}"; fi) \ @@ -61,5 +62,5 @@ for (( i=0; i<${#_TARGETS[*]}; ++i)); do .. done for (( i=0; i<${#_TARGETS[*]}; ++i)); do - echo "Successfully built stage '${_TARGETS[$i]}' for platform ${_PLATFORM} as '${_TAGS[$i]}'" + echo "Successfully built stage '${_TARGETS[$i]}' for platform '${_PLATFORM}' as '${_TAGS[$i]}'" done From 10dd22e0ed8001af00d62d120b2d0fcb7f3f3c8d Mon Sep 17 00:00:00 2001 From: Lennart Reiher Date: Thu, 25 May 2023 15:01:56 +0200 Subject: [PATCH 026/159] rename subaction to action.yml --- .github/actions/{docker-build.yml => docker-build/action.yml} | 2 -- action.yml | 4 ++-- 2 files changed, 2 insertions(+), 4 deletions(-) rename .github/actions/{docker-build.yml => docker-build/action.yml} (93%) diff --git a/.github/actions/docker-build.yml b/.github/actions/docker-build/action.yml similarity index 93% rename from .github/actions/docker-build.yml rename to .github/actions/docker-build/action.yml index e995992..cfd4c56 100644 --- a/.github/actions/docker-build.yml +++ b/.github/actions/docker-build/action.yml @@ -21,8 +21,6 @@ inputs: runs: using: "composite" steps: - - name: checkout code - uses: actions/checkout@v3 - name: docker build run: docker compose -f $DOCKER_COMPOSE_DIR/$DOCKER_COMPOSE_FILE build ${{ inputs.target }} shell: bash diff --git a/action.yml b/action.yml index 477d6d9..695a7ab 100644 --- a/action.yml +++ b/action.yml @@ -27,14 +27,14 @@ runs: token: ${{ inputs.token }} path: $DOCKER_COMPOSE_DIR/docker-ros - name: docker build dev - uses: ./.github/actions/docker-build.yml + uses: ./.github/actions/docker-build with: platform: amd64 target: dev target-image: ghcr.io/$GIHUB_REPOSITORY:latest-dev image-name: ghcr.io/${GIHUB_REPOSITORY}_ci-amd64-dev - name: docker build run - uses: ./.github/actions/docker-build.yml + uses: ./.github/actions/docker-build with: platform: amd64 target: run From 72bd858f0e7134f3ac51992218ba2cf950b0a888 Mon Sep 17 00:00:00 2001 From: Lennart Reiher Date: Thu, 25 May 2023 15:14:46 +0200 Subject: [PATCH 027/159] correctly reference subaction in docker-ros repo --- action.yml | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/action.yml b/action.yml index 695a7ab..2569498 100644 --- a/action.yml +++ b/action.yml @@ -27,14 +27,14 @@ runs: token: ${{ inputs.token }} path: $DOCKER_COMPOSE_DIR/docker-ros - name: docker build dev - uses: ./.github/actions/docker-build + uses: ika-rwth-aachen/docker-ros/.github/actions/docker-build@feature/github-action with: platform: amd64 target: dev target-image: ghcr.io/$GIHUB_REPOSITORY:latest-dev image-name: ghcr.io/${GIHUB_REPOSITORY}_ci-amd64-dev - name: docker build run - uses: ./.github/actions/docker-build + uses: ika-rwth-aachen/docker-ros/.github/actions/docker-build/action.yml@feature/github-action with: platform: amd64 target: run From 9cc03edeab2a33132c3bf1a4aa2e46278161345e Mon Sep 17 00:00:00 2001 From: Lennart Reiher Date: Thu, 25 May 2023 15:17:13 +0200 Subject: [PATCH 028/159] add missing shell commands in subaction --- .github/actions/docker-build/action.yml | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/.github/actions/docker-build/action.yml b/.github/actions/docker-build/action.yml index cfd4c56..1c85dda 100644 --- a/.github/actions/docker-build/action.yml +++ b/.github/actions/docker-build/action.yml @@ -26,5 +26,7 @@ runs: shell: bash - name: docker tag run: docker tag ${{ inputs.target-image }} ${{ inputs.image-name }} + shell: bash - name: docker push - run: docker push ${{ inputs.image-name }} \ No newline at end of file + run: docker push ${{ inputs.image-name }} + shell: bash \ No newline at end of file From a76876fef8ffaa9939a5bfa59f79e98596783e3b Mon Sep 17 00:00:00 2001 From: Lennart Reiher Date: Thu, 25 May 2023 15:20:09 +0200 Subject: [PATCH 029/159] remove unused image-cache input in subaction --- .github/actions/docker-build/action.yml | 4 ---- 1 file changed, 4 deletions(-) diff --git a/.github/actions/docker-build/action.yml b/.github/actions/docker-build/action.yml index 1c85dda..032fda6 100644 --- a/.github/actions/docker-build/action.yml +++ b/.github/actions/docker-build/action.yml @@ -14,10 +14,6 @@ inputs: image-name: description: 'image name' required: true - image-cache: - description: 'image to cache from' - required: false - default: ${{ inputs.image-name }} runs: using: "composite" steps: From 88072077cfd471326fbeff5191383f0ef288e21c Mon Sep 17 00:00:00 2001 From: Lennart Reiher Date: Thu, 25 May 2023 15:22:18 +0200 Subject: [PATCH 030/159] fix inclusion of subaction --- action.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/action.yml b/action.yml index 2569498..ea09558 100644 --- a/action.yml +++ b/action.yml @@ -34,7 +34,7 @@ runs: target-image: ghcr.io/$GIHUB_REPOSITORY:latest-dev image-name: ghcr.io/${GIHUB_REPOSITORY}_ci-amd64-dev - name: docker build run - uses: ika-rwth-aachen/docker-ros/.github/actions/docker-build/action.yml@feature/github-action + uses: ika-rwth-aachen/docker-ros/.github/actions/docker-build@feature/github-action with: platform: amd64 target: run From af523e82833bed8603c0f02aaa4b1636cb0ae1fb Mon Sep 17 00:00:00 2001 From: Lennart Reiher Date: Thu, 25 May 2023 15:39:52 +0200 Subject: [PATCH 031/159] test --- action.yml | 10 ++++++++++ 1 file changed, 10 insertions(+) diff --git a/action.yml b/action.yml index ea09558..7db3ad3 100644 --- a/action.yml +++ b/action.yml @@ -1,6 +1,7 @@ # action.yml name: 'Hello World' description: 'Greet someone' +# TODO: move env (not supported) to inputs? env: DOCKER_COMPOSE_DIR: docker DOCKER_COMPOSE_FILE: docker-compose.yml @@ -18,14 +19,23 @@ runs: steps: - name: checkout code uses: actions/checkout@v3 + - name: pwd1 + run: pwd + shell: bash - name: setup docker buildx uses: docker/setup-buildx-action@v2 + - name: pwd2 + run: pwd + shell: bash - name: checkout docker-ros uses: actions/checkout@v3 with: repository: ika-rwth-aachen/docker-ros token: ${{ inputs.token }} path: $DOCKER_COMPOSE_DIR/docker-ros + - name: pwd3 + run: pwd + shell: bash - name: docker build dev uses: ika-rwth-aachen/docker-ros/.github/actions/docker-build@feature/github-action with: From f2e7edb273164cd906068d3190b5d57744ed4550 Mon Sep 17 00:00:00 2001 From: Lennart Reiher Date: Thu, 25 May 2023 15:41:51 +0200 Subject: [PATCH 032/159] test --- action.yml | 3 +++ 1 file changed, 3 insertions(+) diff --git a/action.yml b/action.yml index 7db3ad3..82c852c 100644 --- a/action.yml +++ b/action.yml @@ -17,6 +17,9 @@ outputs: runs: using: "composite" steps: + - name: pwd0 + run: pwd && ls -la && echo $GITHUB_WORKSPACE + shell: bash - name: checkout code uses: actions/checkout@v3 - name: pwd1 From 88d21bc247910d8514ccf5e5e428d6b0d41b5b1e Mon Sep 17 00:00:00 2001 From: Lennart Reiher Date: Thu, 25 May 2023 15:44:09 +0200 Subject: [PATCH 033/159] test --- action.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/action.yml b/action.yml index 82c852c..0ab2d2e 100644 --- a/action.yml +++ b/action.yml @@ -37,7 +37,7 @@ runs: token: ${{ inputs.token }} path: $DOCKER_COMPOSE_DIR/docker-ros - name: pwd3 - run: pwd + run: pwd && ls -la && ls -la ros1 && ls -la ros1/docker && ls -la ros1/docker/docker-ros shell: bash - name: docker build dev uses: ika-rwth-aachen/docker-ros/.github/actions/docker-build@feature/github-action From 87662b1cd2d9f0144bc1e9481dced2f5e724b360 Mon Sep 17 00:00:00 2001 From: Lennart Reiher Date: Thu, 25 May 2023 15:53:56 +0200 Subject: [PATCH 034/159] fix env variable substitution --- .github/actions/docker-build/action.yml | 4 ++-- action.yml | 22 +++++----------------- 2 files changed, 7 insertions(+), 19 deletions(-) diff --git a/.github/actions/docker-build/action.yml b/.github/actions/docker-build/action.yml index 032fda6..14db5bd 100644 --- a/.github/actions/docker-build/action.yml +++ b/.github/actions/docker-build/action.yml @@ -18,11 +18,11 @@ runs: using: "composite" steps: - name: docker build - run: docker compose -f $DOCKER_COMPOSE_DIR/$DOCKER_COMPOSE_FILE build ${{ inputs.target }} + run: docker compose -f ${DOCKER_COMPOSE_DIR}/${DOCKER_COMPOSE_FILE} build ${{ inputs.target }} shell: bash - name: docker tag run: docker tag ${{ inputs.target-image }} ${{ inputs.image-name }} shell: bash - name: docker push run: docker push ${{ inputs.image-name }} - shell: bash \ No newline at end of file + shell: bash diff --git a/action.yml b/action.yml index 0ab2d2e..de3ae15 100644 --- a/action.yml +++ b/action.yml @@ -17,39 +17,27 @@ outputs: runs: using: "composite" steps: - - name: pwd0 - run: pwd && ls -la && echo $GITHUB_WORKSPACE - shell: bash - name: checkout code uses: actions/checkout@v3 - - name: pwd1 - run: pwd - shell: bash - name: setup docker buildx uses: docker/setup-buildx-action@v2 - - name: pwd2 - run: pwd - shell: bash - name: checkout docker-ros uses: actions/checkout@v3 with: repository: ika-rwth-aachen/docker-ros token: ${{ inputs.token }} - path: $DOCKER_COMPOSE_DIR/docker-ros - - name: pwd3 - run: pwd && ls -la && ls -la ros1 && ls -la ros1/docker && ls -la ros1/docker/docker-ros - shell: bash + path: ${{ env.DOCKER_COMPOSE_DIR }}/docker-ros - name: docker build dev uses: ika-rwth-aachen/docker-ros/.github/actions/docker-build@feature/github-action with: platform: amd64 target: dev - target-image: ghcr.io/$GIHUB_REPOSITORY:latest-dev - image-name: ghcr.io/${GIHUB_REPOSITORY}_ci-amd64-dev + target-image: ghcr.io/${{ env.GIHUB_REPOSITORY }}:latest-dev + image-name: ghcr.io/${{ env.GIHUB_REPOSITORY }}_ci-amd64-dev - name: docker build run uses: ika-rwth-aachen/docker-ros/.github/actions/docker-build@feature/github-action with: platform: amd64 target: run - target-image: ghcr.io/$GIHUB_REPOSITORY:latest - image-name: ghcr.io/${GIHUB_REPOSITORY}_ci-amd64 \ No newline at end of file + target-image: ghcr.io/${{ env.GIHUB_REPOSITORY }}:latest + image-name: ghcr.io/${{ env.GIHUB_REPOSITORY }}_ci-amd64 From 3708f9735b2395fc3bc2a23be8f7997899433abb Mon Sep 17 00:00:00 2001 From: Jean-Pierre Busch Date: Thu, 25 May 2023 15:54:30 +0200 Subject: [PATCH 035/159] test Trigger Workflow and Wait --- .github/workflows/main.yml | 22 +++++++++++----------- 1 file changed, 11 insertions(+), 11 deletions(-) diff --git a/.github/workflows/main.yml b/.github/workflows/main.yml index 371b946..99f6145 100644 --- a/.github/workflows/main.yml +++ b/.github/workflows/main.yml @@ -5,17 +5,17 @@ jobs: name: Trigger docker-ros-ci workflow runs-on: ubuntu-latest steps: - # - name: Trigger docker-ros-ci using repository-dispatch - # id: repository-dispatch - # uses: peter-evans/repository-dispatch@v2 - # with: - # token: ${{ secrets.PAT }} # Personal Access Token with appropriate permissions - # repository: ika-rwth-aachen/docker-ros-ci - # event-type: my-event - # client-payload: '{"ref": "feature/github-workflow"}' - - name: Trigger by API - run: | - curl -X POST -H "Authorization: Bearer ${{ secrets.PAT }}" -H "Accept: application/vnd.github.v3+json" -d '{"ref":"feature/github-workflow"}' "https://api.github.com/repos/ika-rwth-aachen/docker-ros-ci/actions/workflows/main.yml/dispatches" + - name: Trigger Workflow and Wait + uses: convictional/trigger-workflow-and-wait@v1.6.5 + with: + owner: ika-rwth-aachen + repo: docker-ros-ci + github_token: ${{ secrets.PAT }} # Personal Access Token with appropriate permissions + ref: feature/github-workflow + workflow_file_name: mail.yml + #- name: Trigger by API + # run: | + # curl -X POST -H "Authorization: Bearer ${{ secrets.PAT }}" -H "Accept: application/vnd.github.v3+json" -d '{"ref":"feature/github-workflow"}' "https://api.github.com/repos/ika-rwth-aachen/docker-ros-ci/actions/workflows/main.yml/dispatches" # watch_workflow: # name: Watch docker-ros-ci workflow run # runs-on: ubuntu-latest From 05a8226a92c89a346a56ec041d647d042b058d5b Mon Sep 17 00:00:00 2001 From: Jean-Pierre Busch Date: Thu, 25 May 2023 15:58:01 +0200 Subject: [PATCH 036/159] fix typo --- .github/workflows/main.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/main.yml b/.github/workflows/main.yml index 99f6145..fcf1bcf 100644 --- a/.github/workflows/main.yml +++ b/.github/workflows/main.yml @@ -12,7 +12,7 @@ jobs: repo: docker-ros-ci github_token: ${{ secrets.PAT }} # Personal Access Token with appropriate permissions ref: feature/github-workflow - workflow_file_name: mail.yml + workflow_file_name: main.yml #- name: Trigger by API # run: | # curl -X POST -H "Authorization: Bearer ${{ secrets.PAT }}" -H "Accept: application/vnd.github.v3+json" -d '{"ref":"feature/github-workflow"}' "https://api.github.com/repos/ika-rwth-aachen/docker-ros-ci/actions/workflows/main.yml/dispatches" From f0e29a02f17ecccf961c641f839bbfd44562c144 Mon Sep 17 00:00:00 2001 From: Lennart Reiher Date: Thu, 25 May 2023 15:59:26 +0200 Subject: [PATCH 037/159] fix typo in env variable name --- action.yml | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/action.yml b/action.yml index de3ae15..fb250da 100644 --- a/action.yml +++ b/action.yml @@ -32,12 +32,12 @@ runs: with: platform: amd64 target: dev - target-image: ghcr.io/${{ env.GIHUB_REPOSITORY }}:latest-dev - image-name: ghcr.io/${{ env.GIHUB_REPOSITORY }}_ci-amd64-dev + target-image: ghcr.io/${{ env.GITHUB_REPOSITORY }}:latest-dev + image-name: ghcr.io/${{ env.GITHUB_REPOSITORY }}_ci-amd64-dev - name: docker build run uses: ika-rwth-aachen/docker-ros/.github/actions/docker-build@feature/github-action with: platform: amd64 target: run - target-image: ghcr.io/${{ env.GIHUB_REPOSITORY }}:latest - image-name: ghcr.io/${{ env.GIHUB_REPOSITORY }}_ci-amd64 + target-image: ghcr.io/${{ env.GITHUB_REPOSITORY }}:latest + image-name: ghcr.io/${{ env.GITHUB_REPOSITORY }}_ci-amd64 From 8e5b93b1ff6b63ea7aecbdcd6a46c7faa82ead26 Mon Sep 17 00:00:00 2001 From: Jean-Pierre Busch Date: Thu, 25 May 2023 16:09:36 +0200 Subject: [PATCH 038/159] cleanup main.yml --- .github/workflows/main.yml | 25 ++----------------------- 1 file changed, 2 insertions(+), 23 deletions(-) diff --git a/.github/workflows/main.yml b/.github/workflows/main.yml index fcf1bcf..c54a686 100644 --- a/.github/workflows/main.yml +++ b/.github/workflows/main.yml @@ -10,28 +10,7 @@ jobs: with: owner: ika-rwth-aachen repo: docker-ros-ci - github_token: ${{ secrets.PAT }} # Personal Access Token with appropriate permissions ref: feature/github-workflow workflow_file_name: main.yml - #- name: Trigger by API - # run: | - # curl -X POST -H "Authorization: Bearer ${{ secrets.PAT }}" -H "Accept: application/vnd.github.v3+json" -d '{"ref":"feature/github-workflow"}' "https://api.github.com/repos/ika-rwth-aachen/docker-ros-ci/actions/workflows/main.yml/dispatches" -# watch_workflow: -# name: Watch docker-ros-ci workflow run -# runs-on: ubuntu-latest -# needs: trigger_workflow -# steps: -# - name: Check Pipeline Status -# id: check_status -# run: | -# echo TEST ${{ needs.trigger_pipeline.outputs.dispatch.outputs.run_id }} -# while true; do -# sleep 30 -# PIPELINE_STATUS=$(curl --silent --header "Authorization: Bearer ${{ secrets.PAT }}" "https://api.github.com/repos/owner/other-repository/actions/runs/${{ needs.trigger_pipeline.outputs.dispatch.outputs.run_id }}" | jq -r '.status') -# echo "Pipeline status: $PIPELINE_STATUS" -# if [[ $PIPELINE_STATUS == "completed" ]]; then -# break -# elif [[ $PIPELINE_STATUS == "failure" || $PIPELINE_STATUS == "cancelled" ]]; then -# exit 1 -# fi -# done \ No newline at end of file + github_token: ${{ secrets.PAT }} # Personal Access Token with appropriate permissions + client-payload: '{"ref": "${{ env.GITHUB_REF_NAME }}"}' \ No newline at end of file From 9bc312ccb7ee050e22fd68765a1a049cc71f976b Mon Sep 17 00:00:00 2001 From: Lennart Reiher Date: Thu, 25 May 2023 16:20:06 +0200 Subject: [PATCH 039/159] fix image names in build action --- action.yml | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/action.yml b/action.yml index fb250da..903bdb2 100644 --- a/action.yml +++ b/action.yml @@ -32,12 +32,12 @@ runs: with: platform: amd64 target: dev - target-image: ghcr.io/${{ env.GITHUB_REPOSITORY }}:latest-dev - image-name: ghcr.io/${{ env.GITHUB_REPOSITORY }}_ci-amd64-dev + target-image: ghcr.io/${{ github.repository }}:latest-dev + image-name: ghcr.io/${{ github.repository }}:latest-dev_${{ github.ref_name }}_ci-amd64 - name: docker build run uses: ika-rwth-aachen/docker-ros/.github/actions/docker-build@feature/github-action with: platform: amd64 target: run - target-image: ghcr.io/${{ env.GITHUB_REPOSITORY }}:latest - image-name: ghcr.io/${{ env.GITHUB_REPOSITORY }}_ci-amd64 + target-image: ghcr.io/${{ github.repository }}:latest + image-name: ghcr.io/${{ github.repository }}:latest_${{ github.ref_name }}_ci-amd64 From 0224cc0279db185e31d91d779a319c42a1937d95 Mon Sep 17 00:00:00 2001 From: Jean-Pierre Busch Date: Thu, 25 May 2023 16:25:06 +0200 Subject: [PATCH 040/159] change to context env --- .github/workflows/main.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/main.yml b/.github/workflows/main.yml index c54a686..fbb406b 100644 --- a/.github/workflows/main.yml +++ b/.github/workflows/main.yml @@ -13,4 +13,4 @@ jobs: ref: feature/github-workflow workflow_file_name: main.yml github_token: ${{ secrets.PAT }} # Personal Access Token with appropriate permissions - client-payload: '{"ref": "${{ env.GITHUB_REF_NAME }}"}' \ No newline at end of file + client_payload: '{"ref": "${{ github.ref_name }}"}' \ No newline at end of file From 48b1dc3c3dac1f2914c77b6ab8b8b9803bd938a3 Mon Sep 17 00:00:00 2001 From: Lennart Reiher Date: Thu, 25 May 2023 16:31:18 +0200 Subject: [PATCH 041/159] slugify ref name in image tags --- action.yml | 8 ++++++-- 1 file changed, 6 insertions(+), 2 deletions(-) diff --git a/action.yml b/action.yml index 903bdb2..35945d0 100644 --- a/action.yml +++ b/action.yml @@ -17,6 +17,10 @@ outputs: runs: using: "composite" steps: + - id: slugify-ref-name + uses: gacts/github-slug@v1 + with: + to-slug: ${{ github.ref_name }} - name: checkout code uses: actions/checkout@v3 - name: setup docker buildx @@ -33,11 +37,11 @@ runs: platform: amd64 target: dev target-image: ghcr.io/${{ github.repository }}:latest-dev - image-name: ghcr.io/${{ github.repository }}:latest-dev_${{ github.ref_name }}_ci-amd64 + image-name: ghcr.io/${{ github.repository }}:latest-dev_${{ steps.slugify-ref-name.outputs.slug }}_ci-amd64 - name: docker build run uses: ika-rwth-aachen/docker-ros/.github/actions/docker-build@feature/github-action with: platform: amd64 target: run target-image: ghcr.io/${{ github.repository }}:latest - image-name: ghcr.io/${{ github.repository }}:latest_${{ github.ref_name }}_ci-amd64 + image-name: ghcr.io/${{ github.repository }}:latest_${{ steps.slugify-ref-name.outputs.slug }}_ci-amd64 From 645e31b9e30e783526f207124db80caff4246c23 Mon Sep 17 00:00:00 2001 From: Jean-Pierre Busch Date: Thu, 25 May 2023 16:41:03 +0200 Subject: [PATCH 042/159] change client_payload name --- .github/workflows/main.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/main.yml b/.github/workflows/main.yml index fbb406b..9157f58 100644 --- a/.github/workflows/main.yml +++ b/.github/workflows/main.yml @@ -13,4 +13,4 @@ jobs: ref: feature/github-workflow workflow_file_name: main.yml github_token: ${{ secrets.PAT }} # Personal Access Token with appropriate permissions - client_payload: '{"ref": "${{ github.ref_name }}"}' \ No newline at end of file + client_payload: '{"docker-ros-git-ref": "${{ github.ref_name }}"}' \ No newline at end of file From e96800ae04246dae1cebb20cc399d8a5ea872836 Mon Sep 17 00:00:00 2001 From: Lennart Reiher Date: Thu, 25 May 2023 16:55:29 +0200 Subject: [PATCH 043/159] test From 7650c81f5b26e77dfe6062b16c1bddc254ce4720 Mon Sep 17 00:00:00 2001 From: Lennart Reiher Date: Thu, 25 May 2023 17:02:34 +0200 Subject: [PATCH 044/159] docker login to ghcr registry --- action.yml | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/action.yml b/action.yml index 35945d0..dec34de 100644 --- a/action.yml +++ b/action.yml @@ -23,6 +23,12 @@ runs: to-slug: ${{ github.ref_name }} - name: checkout code uses: actions/checkout@v3 + - name: docker login + uses: docker/login-action@v2 + with: + registry: ghcr.io + username: ${{ github.actor }} + password: ${{ secrets.GITHUB_TOKEN }} - name: setup docker buildx uses: docker/setup-buildx-action@v2 - name: checkout docker-ros From de67c7bec3a1250b53ba27237591d645090cc9a1 Mon Sep 17 00:00:00 2001 From: Lennart Reiher Date: Thu, 25 May 2023 17:24:35 +0200 Subject: [PATCH 045/159] try to parameterize docker registry authentication --- action.yml | 18 +++++++++++++++--- 1 file changed, 15 insertions(+), 3 deletions(-) diff --git a/action.yml b/action.yml index dec34de..9284ad9 100644 --- a/action.yml +++ b/action.yml @@ -10,6 +10,18 @@ inputs: description: 'access token for cloning docker-ros' required: true default: '' + docker-registry: + description: 'docker registry' + required: false + default: ghcr.io + docker-registry-username: + description: 'docker registry username' + required: false + default: ${{ github.actor }} + docker-registry-password: + description: 'docker registry username' + required: false + default: ${{ github.token }} outputs: random-number: description: "Random number" @@ -26,9 +38,9 @@ runs: - name: docker login uses: docker/login-action@v2 with: - registry: ghcr.io - username: ${{ github.actor }} - password: ${{ secrets.GITHUB_TOKEN }} + registry: ${{ inputs.docker-registry }} + username: ${{ inputs.docker-registry-username }} + password: ${{ inputs.docker-registry-password }} - name: setup docker buildx uses: docker/setup-buildx-action@v2 - name: checkout docker-ros From f03882f1d176e1b39a6b8b1bfaf8b23530f3e288 Mon Sep 17 00:00:00 2001 From: Lennart Reiher Date: Thu, 25 May 2023 17:27:45 +0200 Subject: [PATCH 046/159] make actions more readable --- .github/actions/docker-build/action.yml | 3 +++ action.yml | 7 +++++++ 2 files changed, 10 insertions(+) diff --git a/.github/actions/docker-build/action.yml b/.github/actions/docker-build/action.yml index 14db5bd..7b1cb5d 100644 --- a/.github/actions/docker-build/action.yml +++ b/.github/actions/docker-build/action.yml @@ -17,12 +17,15 @@ inputs: runs: using: "composite" steps: + - name: docker build run: docker compose -f ${DOCKER_COMPOSE_DIR}/${DOCKER_COMPOSE_FILE} build ${{ inputs.target }} shell: bash + - name: docker tag run: docker tag ${{ inputs.target-image }} ${{ inputs.image-name }} shell: bash + - name: docker push run: docker push ${{ inputs.image-name }} shell: bash diff --git a/action.yml b/action.yml index 9284ad9..4587e57 100644 --- a/action.yml +++ b/action.yml @@ -29,26 +29,32 @@ outputs: runs: using: "composite" steps: + - id: slugify-ref-name uses: gacts/github-slug@v1 with: to-slug: ${{ github.ref_name }} + - name: checkout code uses: actions/checkout@v3 + - name: docker login uses: docker/login-action@v2 with: registry: ${{ inputs.docker-registry }} username: ${{ inputs.docker-registry-username }} password: ${{ inputs.docker-registry-password }} + - name: setup docker buildx uses: docker/setup-buildx-action@v2 + - name: checkout docker-ros uses: actions/checkout@v3 with: repository: ika-rwth-aachen/docker-ros token: ${{ inputs.token }} path: ${{ env.DOCKER_COMPOSE_DIR }}/docker-ros + - name: docker build dev uses: ika-rwth-aachen/docker-ros/.github/actions/docker-build@feature/github-action with: @@ -56,6 +62,7 @@ runs: target: dev target-image: ghcr.io/${{ github.repository }}:latest-dev image-name: ghcr.io/${{ github.repository }}:latest-dev_${{ steps.slugify-ref-name.outputs.slug }}_ci-amd64 + - name: docker build run uses: ika-rwth-aachen/docker-ros/.github/actions/docker-build@feature/github-action with: From e62ba9a7d2952340a02fe4fb408740256b96a081 Mon Sep 17 00:00:00 2001 From: Lennart Reiher Date: Thu, 25 May 2023 17:57:03 +0200 Subject: [PATCH 047/159] let build script only build a single target stage --- build.sh | 56 +++++++++++-------------------- templates/.gitlab-ci.template.yml | 23 +++++-------- 2 files changed, 29 insertions(+), 50 deletions(-) diff --git a/build.sh b/build.sh index 9a97fbd..f537e6b 100755 --- a/build.sh +++ b/build.sh @@ -7,11 +7,10 @@ _BASE_IMAGE="${BASE_IMAGE}" _CACHE_FROM="${CACHE_FROM}" _CACHE_TO="${CACHE_TO}" _COMMAND="${COMMAND}" -_DEV_IMAGE="${DEV_IMAGE}" _GIT_HTTPS_PASSWORD="${GIT_HTTPS_PASSWORD}" _GIT_HTTPS_USER="${GIT_HTTPS_USER}" +_IMAGE="${IMAGE}" _PLATFORM="${PLATFORM}" -_RUN_IMAGE="${RUN_IMAGE}" _TARGET="${TARGET}" # load (unset) variables from .env file @@ -20,47 +19,32 @@ source .env [[ -z "${_CACHE_FROM}" ]] && _CACHE_FROM="${CACHE_FROM}" [[ -z "${_CACHE_TO}" ]] && _CACHE_TO="${CACHE_TO}" [[ -z "${_COMMAND}" ]] && _COMMAND="${COMMAND}" -[[ -z "${_DEV_IMAGE}" ]] && _DEV_IMAGE="${DEV_IMAGE}" [[ -z "${_GIT_HTTPS_PASSWORD}" ]] && _TARGET="${GIT_HTTPS_PASSWORD}" [[ -z "${_GIT_HTTPS_USER}" ]] && _TARGET="${GIT_HTTPS_USER}" +[[ -z "${_IMAGE}" ]] && _IMAGE="${IMAGE}" [[ -z "${_PLATFORM}" ]] && _RUN_IMAGE="${PLATFORM}" -[[ -z "${_RUN_IMAGE}" ]] && _RUN_IMAGE="${RUN_IMAGE}" [[ -z "${_TARGET}" ]] && _TARGET="${TARGET}" # check for required environment variables or set defaults [[ -z "${_BASE_IMAGE}" ]] && echo "Environment variable 'BASE_IMAGE' is required" && exit 1 [[ -z "${_COMMAND}" ]] && echo "Environment variable 'COMMAND' is required" && exit 1 +[[ -z "${_IMAGE}" ]] && echo "Environment variable 'IMAGE' is required" && exit 1 _PLATFORM="${_PLATFORM:-$(dpkg --print-architecture)}" +_TARGET="${_TARGET:-run}" -# evaluate which targets to build -if [[ -z "${_TARGET}" ]]; then - [[ -z "${_DEV_IMAGE}" && -z "${_RUN_IMAGE}" ]] && echo "One of environment variables 'DEV_IMAGE' or 'RUN_IMAGE' is required" && exit 1 - [[ -n "${_DEV_IMAGE}" && -z "${_RUN_IMAGE}" ]] && _TAGS=( "${_DEV_IMAGE}" ) && _TARGETS=( dev ) - [[ -z "${_DEV_IMAGE}" && -n "${_RUN_IMAGE}" ]] && _TAGS=( "${_RUN_IMAGE}" ) && _TARGETS=( run ) - [[ -n "${_DEV_IMAGE}" && -n "${_RUN_IMAGE}" ]] && _TAGS=( "${_DEV_IMAGE}" "${_RUN_IMAGE}" ) && _TARGETS=( dev run ) -else - [[ "${_TARGET}" == "dev" ]] && _TAGS=( "${_DEV_IMAGE}" ) && [[ -z "${_DEV_IMAGE}" ]] && echo "Environment variable 'DEV_IMAGE' is required" && exit 1 - [[ "${_TARGET}" == "run" ]] && _TAGS=( "${_RUN_IMAGE}" ) && [[ -z "${_RUN_IMAGE}" ]] && echo "Environment variable 'RUN_IMAGE' is required" && exit 1 - _TARGETS=( "${_TARGET}" ) -fi - -# build image(s) -for (( i=0; i<${#_TARGETS[*]}; ++i)); do - echo "Building stage '${_TARGETS[$i]}' for platform '${_PLATFORM}' as '${_TAGS[$i]}' ..." - docker buildx build \ - --file docker-ros/Dockerfile \ - --target "${_TARGETS[$i]}" \ - --platform "${_PLATFORM}" \ - --load \ - --tag "${_TAGS[$i]}" \ - $(if [[ -n "${_CACHE_FROM}" ]]; then echo "--cache-from ${_CACHE_FROM}"; fi) \ - $(if [[ -n "${_CACHE_TO}" ]]; then echo "--cache-to ${_CACHE_TO}"; fi) \ - --build-arg BASE_IMAGE="${_BASE_IMAGE}" \ - --build-arg COMMAND="${_COMMAND}" \ - --build-arg GIT_HTTPS_PASSWORD="${_GIT_HTTPS_PASSWORD}" \ - --build-arg GIT_HTTPS_USER="${_GIT_HTTPS_USER}" \ - .. -done -for (( i=0; i<${#_TARGETS[*]}; ++i)); do - echo "Successfully built stage '${_TARGETS[$i]}' for platform '${_PLATFORM}' as '${_TAGS[$i]}'" -done +# build image +echo "Building stage '${_TARGET}' for platform '${_PLATFORM}' as '${_IMAGE}' ..." +docker buildx build \ + --file docker-ros/Dockerfile \ + --target "${_TARGET}" \ + --platform "${_PLATFORM}" \ + --tag "${_IMAGE}" \ + --load \ + $(if [[ -n "${_CACHE_FROM}" ]]; then echo "--cache-from ${_CACHE_FROM}"; fi) \ + $(if [[ -n "${_CACHE_TO}" ]]; then echo "--cache-to ${_CACHE_TO}"; fi) \ + --build-arg BASE_IMAGE="${_BASE_IMAGE}" \ + --build-arg COMMAND="${_COMMAND}" \ + --build-arg GIT_HTTPS_PASSWORD="${_GIT_HTTPS_PASSWORD}" \ + --build-arg GIT_HTTPS_USER="${_GIT_HTTPS_USER}" \ + .. +echo "Successfully built stage '${_TARGET}' for platform '${_PLATFORM}' as '${_IMAGE}'" diff --git a/templates/.gitlab-ci.template.yml b/templates/.gitlab-ci.template.yml index 2804204..68e3179 100644 --- a/templates/.gitlab-ci.template.yml +++ b/templates/.gitlab-ci.template.yml @@ -75,8 +75,7 @@ default: .build: script: - ./docker-ros/build.sh - - docker tag ${IMG_TARGET} ${IMG} - - docker push ${IMG} + - docker push ${IMAGE} dev-amd64: stage: Build dev Images @@ -86,9 +85,8 @@ dev-amd64: variables: PLATFORM: linux/amd64 TARGET: dev - IMG_TARGET: ${IMAGE_DEV_TARGET} - IMG_CACHE: ${IMAGE_DEV_CI_AMD64} - IMG: ${IMAGE_DEV_CI_AMD64} + IMAGE: ${IMAGE_DEV_CI_AMD64} + CACHE_FROM: ${IMAGE_DEV_CI_AMD64} dev-arm64: stage: Build dev Images @@ -99,9 +97,8 @@ dev-arm64: variables: PLATFORM: linux/arm64 TARGET: dev - IMG_TARGET: ${IMAGE_DEV_TARGET} - IMG_CACHE: ${IMAGE_DEV_CI_ARM64} - IMG: ${IMAGE_DEV_CI_ARM64} + IMAGE: ${IMAGE_DEV_CI_ARM64} + CACHE_FROM: ${IMAGE_DEV_CI_ARM64} run-amd64: stage: Build run Images @@ -112,9 +109,8 @@ run-amd64: variables: PLATFORM: linux/amd64 TARGET: run - IMG_TARGET: ${IMAGE_RUN_TARGET} - IMG_CACHE: ${IMAGE_DEV_CI_AMD64} - IMG: ${IMAGE_RUN_CI_AMD64} + IMAGE: ${IMAGE_RUN_CI_AMD64} + CACHE_FROM: ${IMAGE_DEV_CI_AMD64} run-arm64: stage: Build run Images @@ -126,9 +122,8 @@ run-arm64: variables: PLATFORM: linux/arm64 TARGET: run - IMG_TARGET: ${IMAGE_RUN_TARGET} - IMG_CACHE: ${IMAGE_DEV_CI_ARM64} - IMG: ${IMAGE_RUN_CI_ARM64} + IMAGE: ${IMAGE_RUN_CI_ARM64} + CACHE_FROM: ${IMAGE_DEV_CI_ARM64} .test: From b73d933cc10e5fbb03f3d061a2c76163771d8a21 Mon Sep 17 00:00:00 2001 From: Lennart Reiher Date: Thu, 25 May 2023 18:40:33 +0200 Subject: [PATCH 048/159] allow build script to work from anywhere --- build.sh | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/build.sh b/build.sh index f537e6b..a35aebd 100755 --- a/build.sh +++ b/build.sh @@ -14,7 +14,7 @@ _PLATFORM="${PLATFORM}" _TARGET="${TARGET}" # load (unset) variables from .env file -source .env +[[ -f .env ]] && source .env # TODO: configurable/flexible .env file [[ -z "${_BASE_IMAGE}" ]] && _BASE_IMAGE="${BASE_IMAGE}" [[ -z "${_CACHE_FROM}" ]] && _CACHE_FROM="${CACHE_FROM}" [[ -z "${_CACHE_TO}" ]] && _CACHE_TO="${CACHE_TO}" @@ -35,7 +35,7 @@ _TARGET="${_TARGET:-run}" # build image echo "Building stage '${_TARGET}' for platform '${_PLATFORM}' as '${_IMAGE}' ..." docker buildx build \ - --file docker-ros/Dockerfile \ + --file $(dirname $0)/Dockerfile \ --target "${_TARGET}" \ --platform "${_PLATFORM}" \ --tag "${_IMAGE}" \ @@ -46,5 +46,5 @@ docker buildx build \ --build-arg COMMAND="${_COMMAND}" \ --build-arg GIT_HTTPS_PASSWORD="${_GIT_HTTPS_PASSWORD}" \ --build-arg GIT_HTTPS_USER="${_GIT_HTTPS_USER}" \ - .. + . echo "Successfully built stage '${_TARGET}' for platform '${_PLATFORM}' as '${_IMAGE}'" From 3e037f718cac3e4b5ad57bc1b8a7497ec3a994e7 Mon Sep 17 00:00:00 2001 From: Lennart Reiher Date: Thu, 25 May 2023 18:40:50 +0200 Subject: [PATCH 049/159] switch github action to build script approach --- .github/actions/docker-build/action.yml | 29 ++++++---------- action.yml | 45 ++++++++++++++++--------- 2 files changed, 40 insertions(+), 34 deletions(-) diff --git a/.github/actions/docker-build/action.yml b/.github/actions/docker-build/action.yml index 7b1cb5d..b8b4cac 100644 --- a/.github/actions/docker-build/action.yml +++ b/.github/actions/docker-build/action.yml @@ -1,31 +1,22 @@ name: 'Docker build' description: 'Docker build action' -inputs: - platform: - description: 'target platform (e.g. amd64 / arm64)' - required: true - target: - description: 'docker target stage' - required: true - target-image: - description: 'image name in compose file' - required: true - image-name: - description: 'image name' - required: true +# TODO: document somewhere? +# required envvars +# PLATFORM +# TARGET +# BASE_IMAGE +# IMAGE +# COMMAND + runs: using: "composite" steps: - name: docker build - run: docker compose -f ${DOCKER_COMPOSE_DIR}/${DOCKER_COMPOSE_FILE} build ${{ inputs.target }} - shell: bash - - - name: docker tag - run: docker tag ${{ inputs.target-image }} ${{ inputs.image-name }} + run: ${DOCKER_DIR}/docker-ros/build.sh shell: bash - name: docker push - run: docker push ${{ inputs.image-name }} + run: docker push ${IMAGE} shell: bash diff --git a/action.yml b/action.yml index 4587e57..b7cac76 100644 --- a/action.yml +++ b/action.yml @@ -3,14 +3,13 @@ name: 'Hello World' description: 'Greet someone' # TODO: move env (not supported) to inputs? env: - DOCKER_COMPOSE_DIR: docker - DOCKER_COMPOSE_FILE: docker-compose.yml + DOCKER_DIR: docker inputs: token: description: 'access token for cloning docker-ros' required: true default: '' - docker-registry: + docker-registry: # TODO: infer from image name description: 'docker registry' required: false default: ghcr.io @@ -22,6 +21,20 @@ inputs: description: 'docker registry username' required: false default: ${{ github.token }} + base-image: + description: 'base image' + required: true + dev-image: + description: 'dev image' + required: false + default: ghcr.io/${{ github.repository }}:latest-dev + run-image: + description: 'run image' + required: false + default: ghcr.io/${{ github.repository }}:latest + command: + description: 'command' + required: true outputs: random-number: description: "Random number" @@ -53,20 +66,22 @@ runs: with: repository: ika-rwth-aachen/docker-ros token: ${{ inputs.token }} - path: ${{ env.DOCKER_COMPOSE_DIR }}/docker-ros + path: ${{ env.DOCKER_DIR }}/docker-ros - name: docker build dev uses: ika-rwth-aachen/docker-ros/.github/actions/docker-build@feature/github-action - with: - platform: amd64 - target: dev - target-image: ghcr.io/${{ github.repository }}:latest-dev - image-name: ghcr.io/${{ github.repository }}:latest-dev_${{ steps.slugify-ref-name.outputs.slug }}_ci-amd64 - + env: + PLATFORM: amd64 # TODO: hardcoded (also see ci-amd64 postfix below) + TARGET: dev + BASE_IMAGE: ${{ inputs.base-image }} + IMAGE: ${{ inputs.dev-image }}_${{ steps.slugify-ref-name.outputs.slug }}_ci-amd64 + COMMAND: ${{ inputs.command }} # TODO: command not needed for dev image + - name: docker build run uses: ika-rwth-aachen/docker-ros/.github/actions/docker-build@feature/github-action - with: - platform: amd64 - target: run - target-image: ghcr.io/${{ github.repository }}:latest - image-name: ghcr.io/${{ github.repository }}:latest_${{ steps.slugify-ref-name.outputs.slug }}_ci-amd64 + env: + PLATFORM: amd64 + TARGET: run + BASE_IMAGE: ${{ inputs.base-image }} + IMAGE: ${{ inputs.run-image }}_${{ steps.slugify-ref-name.outputs.slug }}_ci-amd64 + COMMAND: ${{ inputs.command }} From 16c431a8524ae4b22275ddf23af7314ca82f9d40 Mon Sep 17 00:00:00 2001 From: Jean-Pierre Busch Date: Thu, 25 May 2023 18:51:34 +0200 Subject: [PATCH 050/159] clone docker-ros branch --- action.yml | 1 + 1 file changed, 1 insertion(+) diff --git a/action.yml b/action.yml index b7cac76..216db94 100644 --- a/action.yml +++ b/action.yml @@ -65,6 +65,7 @@ runs: uses: actions/checkout@v3 with: repository: ika-rwth-aachen/docker-ros + ref: ${{ github.ref_name }} # TODO: desired behavior? token: ${{ inputs.token }} path: ${{ env.DOCKER_DIR }}/docker-ros From 4d97c5ed9898fb814239cf820bc06c3f77d849cc Mon Sep 17 00:00:00 2001 From: Jean-Pierre Busch Date: Thu, 25 May 2023 18:53:36 +0200 Subject: [PATCH 051/159] quick fix --- action.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/action.yml b/action.yml index 216db94..ad69e0b 100644 --- a/action.yml +++ b/action.yml @@ -65,7 +65,7 @@ runs: uses: actions/checkout@v3 with: repository: ika-rwth-aachen/docker-ros - ref: ${{ github.ref_name }} # TODO: desired behavior? + ref: feature/github-action # TODO: desired behavior? token: ${{ inputs.token }} path: ${{ env.DOCKER_DIR }}/docker-ros From b9d6d5f56ddaf31c5bb2f0c2cb5329d3b724aa09 Mon Sep 17 00:00:00 2001 From: Lennart Reiher Date: Thu, 25 May 2023 23:12:51 +0200 Subject: [PATCH 052/159] call build script from correct dir --- .github/actions/docker-build/action.yml | 4 +++- action.yml | 1 + 2 files changed, 4 insertions(+), 1 deletion(-) diff --git a/.github/actions/docker-build/action.yml b/.github/actions/docker-build/action.yml index b8b4cac..cbbfe72 100644 --- a/.github/actions/docker-build/action.yml +++ b/.github/actions/docker-build/action.yml @@ -8,13 +8,15 @@ description: 'Docker build action' # BASE_IMAGE # IMAGE # COMMAND +# ROS_DIR +# DOCKER_DIR runs: using: "composite" steps: - name: docker build - run: ${DOCKER_DIR}/docker-ros/build.sh + run: cd ${ROS_DIR} && ${GITHUB_WORKSPACE}/${DOCKER_DIR}/docker-ros/build.sh shell: bash - name: docker push diff --git a/action.yml b/action.yml index ad69e0b..4755209 100644 --- a/action.yml +++ b/action.yml @@ -3,6 +3,7 @@ name: 'Hello World' description: 'Greet someone' # TODO: move env (not supported) to inputs? env: + ROS_DIR: . DOCKER_DIR: docker inputs: token: From 279a83ca6e62d49f5d268383f3defe658982d822 Mon Sep 17 00:00:00 2001 From: Lennart Reiher Date: Thu, 25 May 2023 23:37:05 +0200 Subject: [PATCH 053/159] build multi-arch images --- .github/actions/docker-build/action.yml | 4 ---- action.yml | 11 +++++++---- build.sh | 2 +- 3 files changed, 8 insertions(+), 9 deletions(-) diff --git a/.github/actions/docker-build/action.yml b/.github/actions/docker-build/action.yml index cbbfe72..90ee56d 100644 --- a/.github/actions/docker-build/action.yml +++ b/.github/actions/docker-build/action.yml @@ -18,7 +18,3 @@ runs: - name: docker build run: cd ${ROS_DIR} && ${GITHUB_WORKSPACE}/${DOCKER_DIR}/docker-ros/build.sh shell: bash - - - name: docker push - run: docker push ${IMAGE} - shell: bash diff --git a/action.yml b/action.yml index 4755209..09f8f88 100644 --- a/action.yml +++ b/action.yml @@ -59,6 +59,9 @@ runs: username: ${{ inputs.docker-registry-username }} password: ${{ inputs.docker-registry-password }} + - name: Set up QEMU + uses: docker/setup-qemu-action@v2 + - name: setup docker buildx uses: docker/setup-buildx-action@v2 @@ -73,17 +76,17 @@ runs: - name: docker build dev uses: ika-rwth-aachen/docker-ros/.github/actions/docker-build@feature/github-action env: - PLATFORM: amd64 # TODO: hardcoded (also see ci-amd64 postfix below) + PLATFORM: amd64,arm64 # TODO: hardcoded (also see ci-amd64 postfix below) TARGET: dev BASE_IMAGE: ${{ inputs.base-image }} - IMAGE: ${{ inputs.dev-image }}_${{ steps.slugify-ref-name.outputs.slug }}_ci-amd64 + IMAGE: ${{ inputs.dev-image }}_${{ steps.slugify-ref-name.outputs.slug }}_ci COMMAND: ${{ inputs.command }} # TODO: command not needed for dev image - name: docker build run uses: ika-rwth-aachen/docker-ros/.github/actions/docker-build@feature/github-action env: - PLATFORM: amd64 + PLATFORM: amd64,arm64 TARGET: run BASE_IMAGE: ${{ inputs.base-image }} - IMAGE: ${{ inputs.run-image }}_${{ steps.slugify-ref-name.outputs.slug }}_ci-amd64 + IMAGE: ${{ inputs.run-image }}_${{ steps.slugify-ref-name.outputs.slug }}_ci COMMAND: ${{ inputs.command }} diff --git a/build.sh b/build.sh index a35aebd..6c43873 100755 --- a/build.sh +++ b/build.sh @@ -39,7 +39,7 @@ docker buildx build \ --target "${_TARGET}" \ --platform "${_PLATFORM}" \ --tag "${_IMAGE}" \ - --load \ + --push \ $(if [[ -n "${_CACHE_FROM}" ]]; then echo "--cache-from ${_CACHE_FROM}"; fi) \ $(if [[ -n "${_CACHE_TO}" ]]; then echo "--cache-to ${_CACHE_TO}"; fi) \ --build-arg BASE_IMAGE="${_BASE_IMAGE}" \ From 428245b7ec48d45ac472a279960ae8737aff457f Mon Sep 17 00:00:00 2001 From: Lennart Reiher Date: Thu, 25 May 2023 23:53:05 +0200 Subject: [PATCH 054/159] add industrial_ci to action --- action.yml | 13 +++++++++++-- 1 file changed, 11 insertions(+), 2 deletions(-) diff --git a/action.yml b/action.yml index 09f8f88..520b35a 100644 --- a/action.yml +++ b/action.yml @@ -76,7 +76,7 @@ runs: - name: docker build dev uses: ika-rwth-aachen/docker-ros/.github/actions/docker-build@feature/github-action env: - PLATFORM: amd64,arm64 # TODO: hardcoded (also see ci-amd64 postfix below) + PLATFORM: amd64 #,arm64 # TODO: hardcoded (also see ci-amd64 postfix below) TARGET: dev BASE_IMAGE: ${{ inputs.base-image }} IMAGE: ${{ inputs.dev-image }}_${{ steps.slugify-ref-name.outputs.slug }}_ci @@ -85,8 +85,17 @@ runs: - name: docker build run uses: ika-rwth-aachen/docker-ros/.github/actions/docker-build@feature/github-action env: - PLATFORM: amd64,arm64 + PLATFORM: amd64 #,arm64 TARGET: run BASE_IMAGE: ${{ inputs.base-image }} IMAGE: ${{ inputs.run-image }}_${{ steps.slugify-ref-name.outputs.slug }}_ci COMMAND: ${{ inputs.command }} + + - name: industrial ci + uses: ros-industrial/industrial_ci@master + env: + UPSTREAM_WORKSPACE: ${{ env.ROS_DIR }}/.repos + TARGET_WORKSPACE: ${{ env.ROS_DIR }} + ADDITIONAL_DEBS: git # TODO AFTER_INIT_EMBED: git config --global url.${CI_SERVER_PROTOCOL}://gitlab-ci-token:${CI_JOB_TOKEN}@${CI_SERVER_HOST}:${CI_SERVER_PORT}.insteadOf ${CI_SERVER_URL} + DOCKER_RUN_OPTS: -u root:root + DOCKER_IMAGE: ${{ inputs.dev-image }}_${{ steps.slugify-ref-name.outputs.slug }}_ci From 30636e77305066984774a55a2e0cd705572edbc9 Mon Sep 17 00:00:00 2001 From: Lennart Reiher Date: Fri, 26 May 2023 00:18:31 +0200 Subject: [PATCH 055/159] group build output log in collapsible --- .github/actions/docker-build/action.yml | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/.github/actions/docker-build/action.yml b/.github/actions/docker-build/action.yml index 90ee56d..bd471f0 100644 --- a/.github/actions/docker-build/action.yml +++ b/.github/actions/docker-build/action.yml @@ -16,5 +16,9 @@ runs: steps: - name: docker build - run: cd ${ROS_DIR} && ${GITHUB_WORKSPACE}/${DOCKER_DIR}/docker-ros/build.sh + run: | + cd ${ROS_DIR} + echo "::group::DOCKER BUILD" + ${GITHUB_WORKSPACE}/${DOCKER_DIR}/docker-ros/build.sh + echo "::endgroup::" shell: bash From 585b4aa53b256c71a80fc526e81d0674fffab1ff Mon Sep 17 00:00:00 2001 From: Lennart Reiher Date: Fri, 26 May 2023 16:00:44 +0200 Subject: [PATCH 056/159] implement build jobs in main ci script --- action.yml | 23 ++++++++------------ build.sh | 64 +++++++++++++++--------------------------------------- ci.sh | 53 ++++++++++++++++++++++++++++++++++++++++++++ 3 files changed, 79 insertions(+), 61 deletions(-) create mode 100755 ci.sh diff --git a/action.yml b/action.yml index 520b35a..8764a67 100644 --- a/action.yml +++ b/action.yml @@ -73,23 +73,18 @@ runs: token: ${{ inputs.token }} path: ${{ env.DOCKER_DIR }}/docker-ros - - name: docker build dev - uses: ika-rwth-aachen/docker-ros/.github/actions/docker-build@feature/github-action + - name: docker build + run: | + cd ${ROS_DIR} + ${GITHUB_WORKSPACE}/${DOCKER_DIR}/docker-ros/ci.sh + shell: bash env: - PLATFORM: amd64 #,arm64 # TODO: hardcoded (also see ci-amd64 postfix below) - TARGET: dev + PLATFORM: amd64 + TARGET: dev,run BASE_IMAGE: ${{ inputs.base-image }} - IMAGE: ${{ inputs.dev-image }}_${{ steps.slugify-ref-name.outputs.slug }}_ci COMMAND: ${{ inputs.command }} # TODO: command not needed for dev image - - - name: docker build run - uses: ika-rwth-aachen/docker-ros/.github/actions/docker-build@feature/github-action - env: - PLATFORM: amd64 #,arm64 - TARGET: run - BASE_IMAGE: ${{ inputs.base-image }} - IMAGE: ${{ inputs.run-image }}_${{ steps.slugify-ref-name.outputs.slug }}_ci - COMMAND: ${{ inputs.command }} + IMAGE: ${{ inputs.run-image }}_${{ steps.slugify-ref-name.outputs.slug }} + DEV_IMAGE: ${{ inputs.dev-image }}_${{ steps.slugify-ref-name.outputs.slug }} - name: industrial ci uses: ros-industrial/industrial_ci@master diff --git a/build.sh b/build.sh index 6c43873..c793841 100755 --- a/build.sh +++ b/build.sh @@ -1,50 +1,20 @@ #!/bin/bash -set -e +build_image() { -# load environment variables -_BASE_IMAGE="${BASE_IMAGE}" -_CACHE_FROM="${CACHE_FROM}" -_CACHE_TO="${CACHE_TO}" -_COMMAND="${COMMAND}" -_GIT_HTTPS_PASSWORD="${GIT_HTTPS_PASSWORD}" -_GIT_HTTPS_USER="${GIT_HTTPS_USER}" -_IMAGE="${IMAGE}" -_PLATFORM="${PLATFORM}" -_TARGET="${TARGET}" - -# load (unset) variables from .env file -[[ -f .env ]] && source .env # TODO: configurable/flexible .env file -[[ -z "${_BASE_IMAGE}" ]] && _BASE_IMAGE="${BASE_IMAGE}" -[[ -z "${_CACHE_FROM}" ]] && _CACHE_FROM="${CACHE_FROM}" -[[ -z "${_CACHE_TO}" ]] && _CACHE_TO="${CACHE_TO}" -[[ -z "${_COMMAND}" ]] && _COMMAND="${COMMAND}" -[[ -z "${_GIT_HTTPS_PASSWORD}" ]] && _TARGET="${GIT_HTTPS_PASSWORD}" -[[ -z "${_GIT_HTTPS_USER}" ]] && _TARGET="${GIT_HTTPS_USER}" -[[ -z "${_IMAGE}" ]] && _IMAGE="${IMAGE}" -[[ -z "${_PLATFORM}" ]] && _RUN_IMAGE="${PLATFORM}" -[[ -z "${_TARGET}" ]] && _TARGET="${TARGET}" - -# check for required environment variables or set defaults -[[ -z "${_BASE_IMAGE}" ]] && echo "Environment variable 'BASE_IMAGE' is required" && exit 1 -[[ -z "${_COMMAND}" ]] && echo "Environment variable 'COMMAND' is required" && exit 1 -[[ -z "${_IMAGE}" ]] && echo "Environment variable 'IMAGE' is required" && exit 1 -_PLATFORM="${_PLATFORM:-$(dpkg --print-architecture)}" -_TARGET="${_TARGET:-run}" - -# build image -echo "Building stage '${_TARGET}' for platform '${_PLATFORM}' as '${_IMAGE}' ..." -docker buildx build \ - --file $(dirname $0)/Dockerfile \ - --target "${_TARGET}" \ - --platform "${_PLATFORM}" \ - --tag "${_IMAGE}" \ - --push \ - $(if [[ -n "${_CACHE_FROM}" ]]; then echo "--cache-from ${_CACHE_FROM}"; fi) \ - $(if [[ -n "${_CACHE_TO}" ]]; then echo "--cache-to ${_CACHE_TO}"; fi) \ - --build-arg BASE_IMAGE="${_BASE_IMAGE}" \ - --build-arg COMMAND="${_COMMAND}" \ - --build-arg GIT_HTTPS_PASSWORD="${_GIT_HTTPS_PASSWORD}" \ - --build-arg GIT_HTTPS_USER="${_GIT_HTTPS_USER}" \ - . -echo "Successfully built stage '${_TARGET}' for platform '${_PLATFORM}' as '${_IMAGE}'" + echo "Building stage '${TARGET}' for platform '${PLATFORM}' as '${IMAGE}' ..." + docker buildx build \ + --file $(dirname $0)/Dockerfile \ + --target "${TARGET}" \ + --platform "${PLATFORM}" \ + --tag "${IMAGE}" \ + --push \ + $(if [[ -n "${CACHE_FROM}" ]]; then echo "--cache-from ${CACHE_FROM}"; fi) \ + $(if [[ -n "${CACHE_TO}" ]]; then echo "--cache-to ${CACHE_TO}"; fi) \ + --build-arg BASE_IMAGE="${BASE_IMAGE}" \ + --build-arg COMMAND="${COMMAND}" \ + --build-arg GIT_HTTPS_PASSWORD="${GIT_HTTPS_PASSWORD}" \ + --build-arg GIT_HTTPS_USER="${GIT_HTTPS_USER}" \ + . + echo "Successfully built stage '${TARGET}' for platform '${PLATFORM}' as '${IMAGE}'" +} diff --git a/ci.sh b/ci.sh new file mode 100755 index 0000000..1a3c2b7 --- /dev/null +++ b/ci.sh @@ -0,0 +1,53 @@ +#!/bin/bash + +set -e + +DOCKER_ROS_PATH="$(cd -P "$(dirname "${0}")" && pwd)" +source "${DOCKER_ROS_PATH}/build.sh" + +require_var() { + if [[ -z "${!1}" ]]; then + echo "Environment variable '${1}' is required" + exit 1 + fi +} + +open_log_group() { + echo "::group::${1}" +} + +close_log_group() { + echo "::endgroup::" +} + +# set defaults for optional variables +TARGET="${TARGET:-run}" +PLATFORM="${PLATFORM:-$(dpkg --print-architecture)}" + +# check for required variables +require_var "BASE_IMAGE" +[[ "${TARGET}" == *"run"* ]] && require_var "COMMAND" +[[ "${TARGET}" == *"dev"* ]] && require_var "DEV_IMAGE" +[[ "${TARGET}" == *"run"* ]] && require_var "IMAGE" + +# set constant variables +CI_POSTFIX="ci" +CI_ARCH_POSTFIX="PLATFORM" + +# parse (potentially) comma-separated lists to arrays +IFS="," read -ra TARGETS <<< "${TARGET}" +IFS="," read -ra PLATFORMS <<< "${PLATFORM}" +unset TARGET +unset PLATFORM + +# loop over targets and platforms to build images +for PLATFORM in "${PLATFORMS[@]}"; do + for TARGET in "${TARGETS[@]}"; do + open_log_group "${TARGET}" + image="${IMAGE}" + [[ "${TARGET}" == "dev" ]] && image="${DEV_IMAGE}" + ci_image="${image}_${CI_POSTFIX}-${!CI_ARCH_POSTFIX}" + IMAGE="${ci_image}" build_image + close_log_group + done +done From f068b1011b766939a247eb1c305ccf47d8cee7a0 Mon Sep 17 00:00:00 2001 From: Lennart Reiher Date: Fri, 26 May 2023 16:08:50 +0200 Subject: [PATCH 057/159] change build script back to loading image instead of pushing --- build.sh | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/build.sh b/build.sh index c793841..259b6d2 100755 --- a/build.sh +++ b/build.sh @@ -8,7 +8,7 @@ build_image() { --target "${TARGET}" \ --platform "${PLATFORM}" \ --tag "${IMAGE}" \ - --push \ + --load \ $(if [[ -n "${CACHE_FROM}" ]]; then echo "--cache-from ${CACHE_FROM}"; fi) \ $(if [[ -n "${CACHE_TO}" ]]; then echo "--cache-to ${CACHE_TO}"; fi) \ --build-arg BASE_IMAGE="${BASE_IMAGE}" \ From eb35ca78ed2bd6347ad7bcf5820ec897a48b4d6a Mon Sep 17 00:00:00 2001 From: Lennart Reiher Date: Fri, 26 May 2023 16:17:19 +0200 Subject: [PATCH 058/159] improve log group title --- ci.sh | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/ci.sh b/ci.sh index 1a3c2b7..b7513e2 100755 --- a/ci.sh +++ b/ci.sh @@ -13,7 +13,7 @@ require_var() { } open_log_group() { - echo "::group::${1}" + echo "::group::[docker-ros] ${1}" } close_log_group() { @@ -43,7 +43,7 @@ unset PLATFORM # loop over targets and platforms to build images for PLATFORM in "${PLATFORMS[@]}"; do for TARGET in "${TARGETS[@]}"; do - open_log_group "${TARGET}" + open_log_group "Build ${TARGET} image (${TARGET})" image="${IMAGE}" [[ "${TARGET}" == "dev" ]] && image="${DEV_IMAGE}" ci_image="${image}_${CI_POSTFIX}-${!CI_ARCH_POSTFIX}" From 8b721dd15f4e1e36809ec6efc6da00ed7464e072 Mon Sep 17 00:00:00 2001 From: Lennart Reiher Date: Fri, 26 May 2023 17:07:08 +0200 Subject: [PATCH 059/159] declare all arguments as action inputs --- action.yml | 135 +++++++++++++++++++++++++---------------------------- build.sh | 3 +- ci.sh | 8 ++-- 3 files changed, 68 insertions(+), 78 deletions(-) diff --git a/action.yml b/action.yml index 8764a67..7767e36 100644 --- a/action.yml +++ b/action.yml @@ -1,96 +1,89 @@ -# action.yml -name: 'Hello World' -description: 'Greet someone' -# TODO: move env (not supported) to inputs? -env: - ROS_DIR: . - DOCKER_DIR: docker +name: "docker-ros" +description: "docker-ros automatically builds development and deployment Docker images for your ROS-based repositories." + inputs: - token: + + token: # TODO: remove, once repos are public description: 'access token for cloning docker-ros' required: true default: '' - docker-registry: # TODO: infer from image name - description: 'docker registry' - required: false - default: ghcr.io - docker-registry-username: - description: 'docker registry username' - required: false - default: ${{ github.actor }} - docker-registry-password: - description: 'docker registry username' - required: false - default: ${{ github.token }} + + target: + description: "Target stage of Dockerfile (comma-separated list) [dev|run]" + default: "run" + + platform: + description: "Target platform architecture (comma-separated list) [amd64|arm64|...]" + base-image: - description: 'base image' + description: "Base image name:tag" required: true - dev-image: - description: 'dev image' - required: false - default: ghcr.io/${{ github.repository }}:latest-dev - run-image: - description: 'run image' - required: false - default: ghcr.io/${{ github.repository }}:latest + command: - description: 'command' - required: true -outputs: - random-number: - description: "Random number" - value: ${{ steps.random-number-generator.outputs.random-number }} + description: "Launch command of run image (required if target=run)" + + image: + description: "Image name:tag of run image" + default: ghcr.io/${{ github.repository }}:latest + + dev-image: + description: "Image name:tag of dev image" + + build-context: + description: "Build context of Docker build process" + default: ${{ github.workspace }} + + registry: # TODO: infer from image name + description: "Docker registry to push images to" + default: ghcr.io + + registry-username: + description: "Docker registry username" + default: ${{ github.actor }} + + registry-password: + description: "Docker registry password" + default: ${{ github.token }} + + runs: using: "composite" steps: - - id: slugify-ref-name - uses: gacts/github-slug@v1 - with: - to-slug: ${{ github.ref_name }} - - - name: checkout code + - name: Checkout repository uses: actions/checkout@v3 - - name: docker login - uses: docker/login-action@v2 + - name: Checkout docker-ros + uses: actions/checkout@v3 with: - registry: ${{ inputs.docker-registry }} - username: ${{ inputs.docker-registry-username }} - password: ${{ inputs.docker-registry-password }} + repository: ika-rwth-aachen/docker-ros + ref: feature/github-action # TODO: desired behavior? + token: ${{ inputs.token }} + path: ${{ inputs.build-context }}/docker/docker-ros - - name: Set up QEMU + - name: Set up QEMU for architecture emulation uses: docker/setup-qemu-action@v2 - - name: setup docker buildx + - name: Set up Docker buildx uses: docker/setup-buildx-action@v2 - - name: checkout docker-ros - uses: actions/checkout@v3 + - name: Login to Docker registry + uses: docker/login-action@v2 with: - repository: ika-rwth-aachen/docker-ros - ref: feature/github-action # TODO: desired behavior? - token: ${{ inputs.token }} - path: ${{ env.DOCKER_DIR }}/docker-ros + registry: ${{ inputs.registry }} + username: ${{ inputs.registry-username }} + password: ${{ inputs.registry-password }} - - name: docker build - run: | - cd ${ROS_DIR} - ${GITHUB_WORKSPACE}/${DOCKER_DIR}/docker-ros/ci.sh + - name: Build images + working-directory: ${{ inputs.build-context }} + run: docker/docker-ros/ci.sh shell: bash env: - PLATFORM: amd64 - TARGET: dev,run + PLATFORM: ${{ inputs.platform }} + TARGET: ${{ inputs.target }} BASE_IMAGE: ${{ inputs.base-image }} - COMMAND: ${{ inputs.command }} # TODO: command not needed for dev image - IMAGE: ${{ inputs.run-image }}_${{ steps.slugify-ref-name.outputs.slug }} - DEV_IMAGE: ${{ inputs.dev-image }}_${{ steps.slugify-ref-name.outputs.slug }} + COMMAND: ${{ inputs.command }} + IMAGE: ${{ inputs.image }} + DEV_IMAGE: ${{ inputs.dev-image }} - - name: industrial ci - uses: ros-industrial/industrial_ci@master - env: - UPSTREAM_WORKSPACE: ${{ env.ROS_DIR }}/.repos - TARGET_WORKSPACE: ${{ env.ROS_DIR }} - ADDITIONAL_DEBS: git # TODO AFTER_INIT_EMBED: git config --global url.${CI_SERVER_PROTOCOL}://gitlab-ci-token:${CI_JOB_TOKEN}@${CI_SERVER_HOST}:${CI_SERVER_PORT}.insteadOf ${CI_SERVER_URL} - DOCKER_RUN_OPTS: -u root:root - DOCKER_IMAGE: ${{ inputs.dev-image }}_${{ steps.slugify-ref-name.outputs.slug }}_ci + # TODO: industrial_ci diff --git a/build.sh b/build.sh index 259b6d2..a669702 100755 --- a/build.sh +++ b/build.sh @@ -9,12 +9,11 @@ build_image() { --platform "${PLATFORM}" \ --tag "${IMAGE}" \ --load \ - $(if [[ -n "${CACHE_FROM}" ]]; then echo "--cache-from ${CACHE_FROM}"; fi) \ - $(if [[ -n "${CACHE_TO}" ]]; then echo "--cache-to ${CACHE_TO}"; fi) \ --build-arg BASE_IMAGE="${BASE_IMAGE}" \ --build-arg COMMAND="${COMMAND}" \ --build-arg GIT_HTTPS_PASSWORD="${GIT_HTTPS_PASSWORD}" \ --build-arg GIT_HTTPS_USER="${GIT_HTTPS_USER}" \ . echo "Successfully built stage '${TARGET}' for platform '${PLATFORM}' as '${IMAGE}'" + # TODO: GIT_HTTPS } diff --git a/ci.sh b/ci.sh index b7513e2..7306c55 100755 --- a/ci.sh +++ b/ci.sh @@ -20,15 +20,13 @@ close_log_group() { echo "::endgroup::" } -# set defaults for optional variables +# check for required variables set defaults for optional variables TARGET="${TARGET:-run}" PLATFORM="${PLATFORM:-$(dpkg --print-architecture)}" - -# check for required variables require_var "BASE_IMAGE" +require_var "IMAGE" [[ "${TARGET}" == *"run"* ]] && require_var "COMMAND" -[[ "${TARGET}" == *"dev"* ]] && require_var "DEV_IMAGE" -[[ "${TARGET}" == *"run"* ]] && require_var "IMAGE" +DEV_IMAGE="${DEV_IMAGE:-${IMAGE}-dev}" # TODO: what if IMAGE has no TAG? # set constant variables CI_POSTFIX="ci" From 786474eceb03e192d556480bab9861039e48a36a Mon Sep 17 00:00:00 2001 From: Lennart Reiher Date: Fri, 26 May 2023 17:51:25 +0200 Subject: [PATCH 060/159] reactivate industrial ci --- action.yml | 10 +++++++++- ci.sh | 6 ++++++ 2 files changed, 15 insertions(+), 1 deletion(-) diff --git a/action.yml b/action.yml index 7767e36..29cfbaa 100644 --- a/action.yml +++ b/action.yml @@ -75,6 +75,7 @@ runs: password: ${{ inputs.registry-password }} - name: Build images + id: build-images working-directory: ${{ inputs.build-context }} run: docker/docker-ros/ci.sh shell: bash @@ -86,4 +87,11 @@ runs: IMAGE: ${{ inputs.image }} DEV_IMAGE: ${{ inputs.dev-image }} - # TODO: industrial_ci + - name: Run industrial_ci + uses: ros-industrial/industrial_ci@master + env: + UPSTREAM_WORKSPACE: ${{ env.ROS_DIR }}/.repos + TARGET_WORKSPACE: ${{ inputs.build-context }} + ADDITIONAL_DEBS: git # TODO AFTER_INIT_EMBED: git config --global url.${CI_SERVER_PROTOCOL}://gitlab-ci-token:${CI_JOB_TOKEN}@${CI_SERVER_HOST}:${CI_SERVER_PORT}.insteadOf ${CI_SERVER_URL} + DOCKER_RUN_OPTS: -u root:root + DOCKER_IMAGE: ${{ steps.build-images.outputs.INDUSTRIAL_CI_IMAGE }} diff --git a/ci.sh b/ci.sh index 7306c55..ddfa4fb 100755 --- a/ci.sh +++ b/ci.sh @@ -32,6 +32,12 @@ DEV_IMAGE="${DEV_IMAGE:-${IMAGE}-dev}" # TODO: what if IMAGE has no TAG? CI_POSTFIX="ci" CI_ARCH_POSTFIX="PLATFORM" +# write image name for industrial_ci to output +# TODO: GitHub-only +industrial_ci_image=${IMAGE} +[[ "${TARGET}" == *"dev"* ]] && industrial_ci_image=${DEV_IMAGE} +echo "INDUSTRIAL_CI_IMAGE=${industrial_ci_image}_${CI_POSTFIX}-$(dpkg --print-architecture)" >> "${GITHUB_OUTPUT}" + # parse (potentially) comma-separated lists to arrays IFS="," read -ra TARGETS <<< "${TARGET}" IFS="," read -ra PLATFORMS <<< "${PLATFORM}" From a0cfd843a91ffbe1ad279370ac26d061f5286133 Mon Sep 17 00:00:00 2001 From: Lennart Reiher Date: Fri, 26 May 2023 17:58:42 +0200 Subject: [PATCH 061/159] add toggle for industrial ci --- action.yml | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/action.yml b/action.yml index 29cfbaa..d4d18ac 100644 --- a/action.yml +++ b/action.yml @@ -45,6 +45,10 @@ inputs: description: "Docker registry password" default: ${{ github.token }} + enable-industrial-ci: + description: "Enable industrial_ci" + default: "false" + runs: using: "composite" @@ -89,6 +93,7 @@ runs: - name: Run industrial_ci uses: ros-industrial/industrial_ci@master + if: ${{ inputs.enable-industrial-ci == 'true' }} env: UPSTREAM_WORKSPACE: ${{ env.ROS_DIR }}/.repos TARGET_WORKSPACE: ${{ inputs.build-context }} From 11e34b3f56d32a108b1a2bf204688e5606629f7d Mon Sep 17 00:00:00 2001 From: Lennart Reiher Date: Fri, 26 May 2023 18:06:01 +0200 Subject: [PATCH 062/159] fix group log message --- ci.sh | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/ci.sh b/ci.sh index ddfa4fb..d4d11f5 100755 --- a/ci.sh +++ b/ci.sh @@ -47,7 +47,7 @@ unset PLATFORM # loop over targets and platforms to build images for PLATFORM in "${PLATFORMS[@]}"; do for TARGET in "${TARGETS[@]}"; do - open_log_group "Build ${TARGET} image (${TARGET})" + open_log_group "Build ${TARGET} image (${PLATFORM})" image="${IMAGE}" [[ "${TARGET}" == "dev" ]] && image="${DEV_IMAGE}" ci_image="${image}_${CI_POSTFIX}-${!CI_ARCH_POSTFIX}" From 1df43d39ea54a74bcf0042cfc348905991d72ef7 Mon Sep 17 00:00:00 2001 From: Lennart Reiher Date: Fri, 26 May 2023 18:09:44 +0200 Subject: [PATCH 063/159] run industrial_ci with local image --- action.yml | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/action.yml b/action.yml index d4d18ac..93cb3eb 100644 --- a/action.yml +++ b/action.yml @@ -47,7 +47,7 @@ inputs: enable-industrial-ci: description: "Enable industrial_ci" - default: "false" + default: false runs: @@ -100,3 +100,4 @@ runs: ADDITIONAL_DEBS: git # TODO AFTER_INIT_EMBED: git config --global url.${CI_SERVER_PROTOCOL}://gitlab-ci-token:${CI_JOB_TOKEN}@${CI_SERVER_HOST}:${CI_SERVER_PORT}.insteadOf ${CI_SERVER_URL} DOCKER_RUN_OPTS: -u root:root DOCKER_IMAGE: ${{ steps.build-images.outputs.INDUSTRIAL_CI_IMAGE }} + DOCKER_PULL: false From 1dfe83d70012744ce8043dabb1e2c5145fd44913 Mon Sep 17 00:00:00 2001 From: Lennart Reiher Date: Fri, 26 May 2023 18:20:52 +0200 Subject: [PATCH 064/159] fix industrial_ci .repos usage --- action.yml | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/action.yml b/action.yml index 93cb3eb..feebd80 100644 --- a/action.yml +++ b/action.yml @@ -91,11 +91,15 @@ runs: IMAGE: ${{ inputs.image }} DEV_IMAGE: ${{ inputs.dev-image }} + - name: Set up industrial_ci + run: test -f ${{ inputs.build-context }}/.repos || echo "repositories:" > ${{ inputs.build-context }}/.repos + shell: bash + - name: Run industrial_ci uses: ros-industrial/industrial_ci@master if: ${{ inputs.enable-industrial-ci == 'true' }} env: - UPSTREAM_WORKSPACE: ${{ env.ROS_DIR }}/.repos + UPSTREAM_WORKSPACE: ${{ inputs.build-context }}/.repos TARGET_WORKSPACE: ${{ inputs.build-context }} ADDITIONAL_DEBS: git # TODO AFTER_INIT_EMBED: git config --global url.${CI_SERVER_PROTOCOL}://gitlab-ci-token:${CI_JOB_TOKEN}@${CI_SERVER_HOST}:${CI_SERVER_PORT}.insteadOf ${CI_SERVER_URL} DOCKER_RUN_OPTS: -u root:root From 92c738c2f2c5599c4cf51284e864342aca659d5e Mon Sep 17 00:00:00 2001 From: Lennart Reiher Date: Fri, 26 May 2023 18:40:20 +0200 Subject: [PATCH 065/159] add final step to push multi-arch images using buildx build --push --- action.yml | 18 ++++++++++++++++-- build.sh | 2 +- push.sh | 42 ++++++++++++++++++++++++++++++++++++++++++ 3 files changed, 59 insertions(+), 3 deletions(-) create mode 100755 push.sh diff --git a/action.yml b/action.yml index feebd80..ed046a2 100644 --- a/action.yml +++ b/action.yml @@ -81,8 +81,8 @@ runs: - name: Build images id: build-images working-directory: ${{ inputs.build-context }} - run: docker/docker-ros/ci.sh shell: bash + run: docker/docker-ros/ci.sh env: PLATFORM: ${{ inputs.platform }} TARGET: ${{ inputs.target }} @@ -92,8 +92,8 @@ runs: DEV_IMAGE: ${{ inputs.dev-image }} - name: Set up industrial_ci - run: test -f ${{ inputs.build-context }}/.repos || echo "repositories:" > ${{ inputs.build-context }}/.repos shell: bash + run: test -f ${{ inputs.build-context }}/.repos || echo "repositories:" > ${{ inputs.build-context }}/.repos - name: Run industrial_ci uses: ros-industrial/industrial_ci@master @@ -105,3 +105,17 @@ runs: DOCKER_RUN_OPTS: -u root:root DOCKER_IMAGE: ${{ steps.build-images.outputs.INDUSTRIAL_CI_IMAGE }} DOCKER_PULL: false + + - name: Push images + working-directory: ${{ inputs.build-context }} + shell: bash + run: docker/docker-ros/push.sh + env: + PLATFORM: ${{ inputs.platform }} + TARGET: ${{ inputs.target }} + BASE_IMAGE: ${{ inputs.base-image }} + COMMAND: ${{ inputs.command }} + IMAGE: ${{ inputs.image }} + DEV_IMAGE: ${{ inputs.dev-image }} + # TODO: use same script for push and ci + # TODO: push branch names \ No newline at end of file diff --git a/build.sh b/build.sh index a669702..e5386c2 100755 --- a/build.sh +++ b/build.sh @@ -8,7 +8,7 @@ build_image() { --target "${TARGET}" \ --platform "${PLATFORM}" \ --tag "${IMAGE}" \ - --load \ + $(if [[ "${ENABLE_IMAGE_PUSH}" == "true" ]]; then echo "--push"; else echo "--load"; fi) \ --build-arg BASE_IMAGE="${BASE_IMAGE}" \ --build-arg COMMAND="${COMMAND}" \ --build-arg GIT_HTTPS_PASSWORD="${GIT_HTTPS_PASSWORD}" \ diff --git a/push.sh b/push.sh new file mode 100755 index 0000000..7c4d922 --- /dev/null +++ b/push.sh @@ -0,0 +1,42 @@ +#!/bin/bash + +set -e + +DOCKER_ROS_PATH="$(cd -P "$(dirname "${0}")" && pwd)" +source "${DOCKER_ROS_PATH}/build.sh" + +require_var() { + if [[ -z "${!1}" ]]; then + echo "Environment variable '${1}' is required" + exit 1 + fi +} + +open_log_group() { + echo "::group::[docker-ros] ${1}" +} + +close_log_group() { + echo "::endgroup::" +} + +# check for required variables set defaults for optional variables +TARGET="${TARGET:-run}" +PLATFORM="${PLATFORM:-$(dpkg --print-architecture)}" +require_var "BASE_IMAGE" +require_var "IMAGE" +[[ "${TARGET}" == *"run"* ]] && require_var "COMMAND" +DEV_IMAGE="${DEV_IMAGE:-${IMAGE}-dev}" # TODO: what if IMAGE has no TAG? + +# parse (potentially) comma-separated lists to arrays +IFS="," read -ra TARGETS <<< "${TARGET}" +unset TARGET + +# loop over targets to push multi-arch images +for TARGET in "${TARGETS[@]}"; do + open_log_group "Push ${TARGET} image (${PLATFORM[*]})" + image="${IMAGE}" + [[ "${TARGET}" == "dev" ]] && image="${DEV_IMAGE}" + ENABLE_IMAGE_PUSH="true" IMAGE="${image}" build_image + close_log_group +done From 6c84b19672097777ca23b968b39b34bdeafe5a3f Mon Sep 17 00:00:00 2001 From: Lennart Reiher Date: Fri, 26 May 2023 23:57:44 +0200 Subject: [PATCH 066/159] merge push.sh with ci.sh --- action.yml | 8 +++++--- ci.sh | 23 +++++++++++++++-------- push.sh | 42 ------------------------------------------ 3 files changed, 20 insertions(+), 53 deletions(-) delete mode 100755 push.sh diff --git a/action.yml b/action.yml index ed046a2..204fe90 100644 --- a/action.yml +++ b/action.yml @@ -90,6 +90,7 @@ runs: COMMAND: ${{ inputs.command }} IMAGE: ${{ inputs.image }} DEV_IMAGE: ${{ inputs.dev-image }} + ENABLE_IMAGE_CI_POSTFIX: true - name: Set up industrial_ci shell: bash @@ -109,7 +110,7 @@ runs: - name: Push images working-directory: ${{ inputs.build-context }} shell: bash - run: docker/docker-ros/push.sh + run: docker/docker-ros/ci.sh env: PLATFORM: ${{ inputs.platform }} TARGET: ${{ inputs.target }} @@ -117,5 +118,6 @@ runs: COMMAND: ${{ inputs.command }} IMAGE: ${{ inputs.image }} DEV_IMAGE: ${{ inputs.dev-image }} - # TODO: use same script for push and ci - # TODO: push branch names \ No newline at end of file + ENABLE_IMAGE_PUSH: true + ENABLE_MULTIARCH_BUILD: true + # TODO: push branch names diff --git a/ci.sh b/ci.sh index d4d11f5..b0189c8 100755 --- a/ci.sh +++ b/ci.sh @@ -20,17 +20,20 @@ close_log_group() { echo "::endgroup::" } -# check for required variables set defaults for optional variables +# set constant variables +CI_POSTFIX="ci" +CI_ARCH_POSTFIX="PLATFORM" + +# check for required variables and set defaults for optional variables TARGET="${TARGET:-run}" PLATFORM="${PLATFORM:-$(dpkg --print-architecture)}" require_var "BASE_IMAGE" require_var "IMAGE" [[ "${TARGET}" == *"run"* ]] && require_var "COMMAND" DEV_IMAGE="${DEV_IMAGE:-${IMAGE}-dev}" # TODO: what if IMAGE has no TAG? - -# set constant variables -CI_POSTFIX="ci" -CI_ARCH_POSTFIX="PLATFORM" +ENABLE_IMAGE_CI_POSTFIX="${ENABLE_IMAGE_CI_POSTFIX:-false}" +ENABLE_IMAGE_PUSH="${ENABLE_IMAGE_PUSH:-false}" +ENABLE_MULTIARCH_BUILD="${ENABLE_MULTIARCH_BUILD:-false}" # write image name for industrial_ci to output # TODO: GitHub-only @@ -40,7 +43,11 @@ echo "INDUSTRIAL_CI_IMAGE=${industrial_ci_image}_${CI_POSTFIX}-$(dpkg --print-ar # parse (potentially) comma-separated lists to arrays IFS="," read -ra TARGETS <<< "${TARGET}" -IFS="," read -ra PLATFORMS <<< "${PLATFORM}" +if [[ "${ENABLE_MULTIARCH_BUILD}" == "true" ]]; then + IFS="," read -ra PLATFORMS <<< "${PLATFORM}" +else + PLATFORMS=( "${PLATFORM}" ) +fi unset TARGET unset PLATFORM @@ -50,8 +57,8 @@ for PLATFORM in "${PLATFORMS[@]}"; do open_log_group "Build ${TARGET} image (${PLATFORM})" image="${IMAGE}" [[ "${TARGET}" == "dev" ]] && image="${DEV_IMAGE}" - ci_image="${image}_${CI_POSTFIX}-${!CI_ARCH_POSTFIX}" - IMAGE="${ci_image}" build_image + [[ "${ENABLE_IMAGE_CI_POSTFIX}" == "true" ]] && image="${image}_${CI_POSTFIX}-${!CI_ARCH_POSTFIX}" + IMAGE="${image}" build_image close_log_group done done diff --git a/push.sh b/push.sh deleted file mode 100755 index 7c4d922..0000000 --- a/push.sh +++ /dev/null @@ -1,42 +0,0 @@ -#!/bin/bash - -set -e - -DOCKER_ROS_PATH="$(cd -P "$(dirname "${0}")" && pwd)" -source "${DOCKER_ROS_PATH}/build.sh" - -require_var() { - if [[ -z "${!1}" ]]; then - echo "Environment variable '${1}' is required" - exit 1 - fi -} - -open_log_group() { - echo "::group::[docker-ros] ${1}" -} - -close_log_group() { - echo "::endgroup::" -} - -# check for required variables set defaults for optional variables -TARGET="${TARGET:-run}" -PLATFORM="${PLATFORM:-$(dpkg --print-architecture)}" -require_var "BASE_IMAGE" -require_var "IMAGE" -[[ "${TARGET}" == *"run"* ]] && require_var "COMMAND" -DEV_IMAGE="${DEV_IMAGE:-${IMAGE}-dev}" # TODO: what if IMAGE has no TAG? - -# parse (potentially) comma-separated lists to arrays -IFS="," read -ra TARGETS <<< "${TARGET}" -unset TARGET - -# loop over targets to push multi-arch images -for TARGET in "${TARGETS[@]}"; do - open_log_group "Push ${TARGET} image (${PLATFORM[*]})" - image="${IMAGE}" - [[ "${TARGET}" == "dev" ]] && image="${DEV_IMAGE}" - ENABLE_IMAGE_PUSH="true" IMAGE="${image}" build_image - close_log_group -done From 1281f7c2fb56149d147f03ada60ba0ee92c72552 Mon Sep 17 00:00:00 2001 From: Lennart Reiher Date: Sat, 27 May 2023 00:20:12 +0200 Subject: [PATCH 067/159] add branch to image name if not on default branch --- action.yml | 3 +-- ci.sh | 8 ++------ 2 files changed, 3 insertions(+), 8 deletions(-) diff --git a/action.yml b/action.yml index 204fe90..e38c0d5 100644 --- a/action.yml +++ b/action.yml @@ -90,7 +90,6 @@ runs: COMMAND: ${{ inputs.command }} IMAGE: ${{ inputs.image }} DEV_IMAGE: ${{ inputs.dev-image }} - ENABLE_IMAGE_CI_POSTFIX: true - name: Set up industrial_ci shell: bash @@ -120,4 +119,4 @@ runs: DEV_IMAGE: ${{ inputs.dev-image }} ENABLE_IMAGE_PUSH: true ENABLE_MULTIARCH_BUILD: true - # TODO: push branch names + IMAGE_POSTFIX: ${{ github.ref != format('refs/heads/{0}', github.event.repository.default_branch) && '_${{ steps.slugify-ref-name.outputs.slug }}_ci' || '' }} diff --git a/ci.sh b/ci.sh index b0189c8..b5630bd 100755 --- a/ci.sh +++ b/ci.sh @@ -20,10 +20,6 @@ close_log_group() { echo "::endgroup::" } -# set constant variables -CI_POSTFIX="ci" -CI_ARCH_POSTFIX="PLATFORM" - # check for required variables and set defaults for optional variables TARGET="${TARGET:-run}" PLATFORM="${PLATFORM:-$(dpkg --print-architecture)}" @@ -31,9 +27,9 @@ require_var "BASE_IMAGE" require_var "IMAGE" [[ "${TARGET}" == *"run"* ]] && require_var "COMMAND" DEV_IMAGE="${DEV_IMAGE:-${IMAGE}-dev}" # TODO: what if IMAGE has no TAG? -ENABLE_IMAGE_CI_POSTFIX="${ENABLE_IMAGE_CI_POSTFIX:-false}" ENABLE_IMAGE_PUSH="${ENABLE_IMAGE_PUSH:-false}" ENABLE_MULTIARCH_BUILD="${ENABLE_MULTIARCH_BUILD:-false}" +IMAGE_POSTFIX="${IMAGE_POSTFIX:-""}" # write image name for industrial_ci to output # TODO: GitHub-only @@ -57,7 +53,7 @@ for PLATFORM in "${PLATFORMS[@]}"; do open_log_group "Build ${TARGET} image (${PLATFORM})" image="${IMAGE}" [[ "${TARGET}" == "dev" ]] && image="${DEV_IMAGE}" - [[ "${ENABLE_IMAGE_CI_POSTFIX}" == "true" ]] && image="${image}_${CI_POSTFIX}-${!CI_ARCH_POSTFIX}" + [[ -n "${IMAGE_POSTFIX}" ]] && image="${image}${!IMAGE_POSTFIX}" IMAGE="${image}" build_image close_log_group done From ae583e2d5c075adb8c3c4f0790f86e47a721dc63 Mon Sep 17 00:00:00 2001 From: Lennart Reiher Date: Sat, 27 May 2023 00:36:54 +0200 Subject: [PATCH 068/159] reorganize files --- action.yml | 4 ++-- Dockerfile => docker/Dockerfile | 4 ++-- entrypoint.sh => docker/entrypoint.sh | 0 recursive_vcs_import.py => docker/recursive_vcs_import.py | 0 build.sh => scripts/build.sh | 3 ++- ci.sh => scripts/ci.sh | 4 ++-- 6 files changed, 8 insertions(+), 7 deletions(-) rename Dockerfile => docker/Dockerfile (98%) rename entrypoint.sh => docker/entrypoint.sh (100%) rename recursive_vcs_import.py => docker/recursive_vcs_import.py (100%) rename build.sh => scripts/build.sh (88%) rename ci.sh => scripts/ci.sh (93%) diff --git a/action.yml b/action.yml index e38c0d5..b9e5f3b 100644 --- a/action.yml +++ b/action.yml @@ -82,7 +82,7 @@ runs: id: build-images working-directory: ${{ inputs.build-context }} shell: bash - run: docker/docker-ros/ci.sh + run: docker/docker-ros/scripts/ci.sh env: PLATFORM: ${{ inputs.platform }} TARGET: ${{ inputs.target }} @@ -109,7 +109,7 @@ runs: - name: Push images working-directory: ${{ inputs.build-context }} shell: bash - run: docker/docker-ros/ci.sh + run: docker/docker-ros/scripts/ci.sh env: PLATFORM: ${{ inputs.platform }} TARGET: ${{ inputs.target }} diff --git a/Dockerfile b/docker/Dockerfile similarity index 98% rename from Dockerfile rename to docker/Dockerfile index 85b083c..21758f2 100644 --- a/Dockerfile +++ b/docker/Dockerfile @@ -53,7 +53,7 @@ ARG GIT_HTTPS_PASSWORD= RUN if [ ! -z ${GIT_HTTPS_USER} ]; then \ git config --global url.https://${GIT_HTTPS_USER}:${GIT_HTTPS_PASSWORD}@gitlab.ika.rwth-aachen.de.insteadOf ${GIT_HTTPS_URL} ; \ fi -COPY docker/docker-ros/recursive_vcs_import.py /usr/local/bin +COPY docker/docker-ros/docker/recursive_vcs_import.py /usr/local/bin RUN apt-get update && \ apt-get install -y python-is-python3 && \ rm -rf /var/lib/apt/lists/* @@ -149,7 +149,7 @@ RUN apt-get update && \ RUN echo "source /opt/ros/$ROS_DISTRO/setup.bash" >> ~/.bashrc # set entrypoint -COPY docker/docker-ros/entrypoint.sh / +COPY docker/docker-ros/docker/entrypoint.sh / ENTRYPOINT ["/entrypoint.sh"] ############ dev ############################################################### diff --git a/entrypoint.sh b/docker/entrypoint.sh similarity index 100% rename from entrypoint.sh rename to docker/entrypoint.sh diff --git a/recursive_vcs_import.py b/docker/recursive_vcs_import.py similarity index 100% rename from recursive_vcs_import.py rename to docker/recursive_vcs_import.py diff --git a/build.sh b/scripts/build.sh similarity index 88% rename from build.sh rename to scripts/build.sh index e5386c2..b51d6d9 100755 --- a/build.sh +++ b/scripts/build.sh @@ -4,7 +4,7 @@ build_image() { echo "Building stage '${TARGET}' for platform '${PLATFORM}' as '${IMAGE}' ..." docker buildx build \ - --file $(dirname $0)/Dockerfile \ + --file $(dirname $0)/../docker/Dockerfile \ --target "${TARGET}" \ --platform "${PLATFORM}" \ --tag "${IMAGE}" \ @@ -16,4 +16,5 @@ build_image() { . echo "Successfully built stage '${TARGET}' for platform '${PLATFORM}' as '${IMAGE}'" # TODO: GIT_HTTPS + # TODO: support local build } diff --git a/ci.sh b/scripts/ci.sh similarity index 93% rename from ci.sh rename to scripts/ci.sh index b5630bd..aadf2a0 100755 --- a/ci.sh +++ b/scripts/ci.sh @@ -2,8 +2,8 @@ set -e -DOCKER_ROS_PATH="$(cd -P "$(dirname "${0}")" && pwd)" -source "${DOCKER_ROS_PATH}/build.sh" +DOCKER_ROS_PATH="$(realpath "$(cd -P "$(dirname "${0}")" && pwd)"/..)" +source "${DOCKER_ROS_PATH}/scripts/build.sh" require_var() { if [[ -z "${!1}" ]]; then From 644e3fce27aac3d0b74d9fe2fb498f6ecc02c24a Mon Sep 17 00:00:00 2001 From: Lennart Reiher Date: Sat, 27 May 2023 00:48:21 +0200 Subject: [PATCH 069/159] fix industrial_ci image name after postfix changes --- scripts/ci.sh | 13 ++++++++----- 1 file changed, 8 insertions(+), 5 deletions(-) diff --git a/scripts/ci.sh b/scripts/ci.sh index aadf2a0..ed8fb7c 100755 --- a/scripts/ci.sh +++ b/scripts/ci.sh @@ -29,13 +29,15 @@ require_var "IMAGE" DEV_IMAGE="${DEV_IMAGE:-${IMAGE}-dev}" # TODO: what if IMAGE has no TAG? ENABLE_IMAGE_PUSH="${ENABLE_IMAGE_PUSH:-false}" ENABLE_MULTIARCH_BUILD="${ENABLE_MULTIARCH_BUILD:-false}" -IMAGE_POSTFIX="${IMAGE_POSTFIX:-""}" +IMAGE_POSTFIX="${IMAGE_POSTFIX:-"_ci"}" # write image name for industrial_ci to output # TODO: GitHub-only -industrial_ci_image=${IMAGE} -[[ "${TARGET}" == *"dev"* ]] && industrial_ci_image=${DEV_IMAGE} -echo "INDUSTRIAL_CI_IMAGE=${industrial_ci_image}_${CI_POSTFIX}-$(dpkg --print-architecture)" >> "${GITHUB_OUTPUT}" +industrial_ci_image="${IMAGE}" +[[ "${TARGET}" == *"dev"* ]] && industrial_ci_image="${DEV_IMAGE}" +industrial_ci_image="${industrial_ci_image}${IMAGE_POSTFIX}" +[[ "${ENABLE_MULTIARCH_BUILD}" != "true" ]] && industrial_ci_image="${industrial_ci_image}-$(dpkg --print-architecture)" +echo "INDUSTRIAL_CI_IMAGE=${industrial_ci_image}" >> "${GITHUB_OUTPUT}" # parse (potentially) comma-separated lists to arrays IFS="," read -ra TARGETS <<< "${TARGET}" @@ -53,7 +55,8 @@ for PLATFORM in "${PLATFORMS[@]}"; do open_log_group "Build ${TARGET} image (${PLATFORM})" image="${IMAGE}" [[ "${TARGET}" == "dev" ]] && image="${DEV_IMAGE}" - [[ -n "${IMAGE_POSTFIX}" ]] && image="${image}${!IMAGE_POSTFIX}" + [[ -n "${IMAGE_POSTFIX}" ]] && image="${image}${IMAGE_POSTFIX}" + [[ "${ENABLE_MULTIARCH_BUILD}" != "true" ]] && image="${image}-${TARGET}" IMAGE="${image}" build_image close_log_group done From 3d8bc04b71c125338bd72d764a20be6205c83905 Mon Sep 17 00:00:00 2001 From: Lennart Reiher Date: Sat, 27 May 2023 00:50:35 +0200 Subject: [PATCH 070/159] reenable local build using build.sh --- scripts/build.sh | 20 +++++++++++++++++++- scripts/ci.sh | 19 +++---------------- scripts/utils.sh | 16 ++++++++++++++++ 3 files changed, 38 insertions(+), 17 deletions(-) create mode 100644 scripts/utils.sh diff --git a/scripts/build.sh b/scripts/build.sh index b51d6d9..b79f5ae 100755 --- a/scripts/build.sh +++ b/scripts/build.sh @@ -1,5 +1,11 @@ #!/bin/bash +set -e + +ROOT_PATH="$(realpath "$(cd -P "$(dirname "${0}")" && pwd)"/..)" +source "${ROOT_PATH}/scripts/utils.sh" + + build_image() { echo "Building stage '${TARGET}' for platform '${PLATFORM}' as '${IMAGE}' ..." @@ -16,5 +22,17 @@ build_image() { . echo "Successfully built stage '${TARGET}' for platform '${PLATFORM}' as '${IMAGE}'" # TODO: GIT_HTTPS - # TODO: support local build } + + +# check if script is executed +if [[ "${BASH_SOURCE[0]}" == "${0}" ]]; then + # check for required variables and set defaults for optional variables + TARGET="${TARGET:-run}" + PLATFORM="${PLATFORM:-$(dpkg --print-architecture)}" + require_var "BASE_IMAGE" + require_var "IMAGE" + [[ "${TARGET}" == *"run"* ]] && require_var "COMMAND" + ENABLE_IMAGE_PUSH="${ENABLE_IMAGE_PUSH:-false}" + build_image +fi diff --git a/scripts/ci.sh b/scripts/ci.sh index ed8fb7c..b0d01c3 100755 --- a/scripts/ci.sh +++ b/scripts/ci.sh @@ -2,23 +2,10 @@ set -e -DOCKER_ROS_PATH="$(realpath "$(cd -P "$(dirname "${0}")" && pwd)"/..)" -source "${DOCKER_ROS_PATH}/scripts/build.sh" +ROOT_PATH="$(realpath "$(cd -P "$(dirname "${0}")" && pwd)"/..)" +source "${ROOT_PATH}/scripts/build.sh" +source "${ROOT_PATH}/scripts/utils.sh" -require_var() { - if [[ -z "${!1}" ]]; then - echo "Environment variable '${1}' is required" - exit 1 - fi -} - -open_log_group() { - echo "::group::[docker-ros] ${1}" -} - -close_log_group() { - echo "::endgroup::" -} # check for required variables and set defaults for optional variables TARGET="${TARGET:-run}" diff --git a/scripts/utils.sh b/scripts/utils.sh new file mode 100644 index 0000000..31ad494 --- /dev/null +++ b/scripts/utils.sh @@ -0,0 +1,16 @@ +#!/bin/bash + +require_var() { + if [[ -z "${!1}" ]]; then + echo "Environment variable '${1}' is required" + exit 1 + fi +} + +open_log_group() { + echo "::group::[docker-ros] ${1}" +} + +close_log_group() { + echo "::endgroup::" +} From 8ada9c5a043e27f733aebbca2c68b61539fe9d66 Mon Sep 17 00:00:00 2001 From: Lennart Reiher Date: Sat, 27 May 2023 01:16:04 +0200 Subject: [PATCH 071/159] fix typo in image postfix --- scripts/ci.sh | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/scripts/ci.sh b/scripts/ci.sh index b0d01c3..cd6be14 100755 --- a/scripts/ci.sh +++ b/scripts/ci.sh @@ -43,7 +43,7 @@ for PLATFORM in "${PLATFORMS[@]}"; do image="${IMAGE}" [[ "${TARGET}" == "dev" ]] && image="${DEV_IMAGE}" [[ -n "${IMAGE_POSTFIX}" ]] && image="${image}${IMAGE_POSTFIX}" - [[ "${ENABLE_MULTIARCH_BUILD}" != "true" ]] && image="${image}-${TARGET}" + [[ "${ENABLE_MULTIARCH_BUILD}" != "true" ]] && image="${image}-${PLATFORM}" IMAGE="${image}" build_image close_log_group done From b002fdcf0a8b5cf32cdfa5478183ddab79d25c06 Mon Sep 17 00:00:00 2001 From: Lennart Reiher Date: Sat, 27 May 2023 01:28:46 +0200 Subject: [PATCH 072/159] readd missing slugify action --- action.yml | 8 +++++++- 1 file changed, 7 insertions(+), 1 deletion(-) diff --git a/action.yml b/action.yml index b9e5f3b..8910a9c 100644 --- a/action.yml +++ b/action.yml @@ -54,6 +54,12 @@ runs: using: "composite" steps: + - name: Slugify ref name + id: slugify-ref-name + uses: gacts/github-slug@v1 + with: + to-slug: ${{ github.ref_name }} + - name: Checkout repository uses: actions/checkout@v3 @@ -119,4 +125,4 @@ runs: DEV_IMAGE: ${{ inputs.dev-image }} ENABLE_IMAGE_PUSH: true ENABLE_MULTIARCH_BUILD: true - IMAGE_POSTFIX: ${{ github.ref != format('refs/heads/{0}', github.event.repository.default_branch) && '_${{ steps.slugify-ref-name.outputs.slug }}_ci' || '' }} + IMAGE_POSTFIX: ${{ github.ref != format('refs/heads/{0}', github.event.repository.default_branch) && "_${{ steps.slugify-ref-name.outputs.slug }}_ci" || "" }} From 2a7827698ad7ca0894cef7760edb7b6b8a66e235 Mon Sep 17 00:00:00 2001 From: Jean-Pierre Busch Date: Tue, 30 May 2023 11:27:56 +0200 Subject: [PATCH 073/159] use single quotes --- action.yml | 2 +- scripts/ci.sh | 4 ++-- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/action.yml b/action.yml index 8910a9c..e01f468 100644 --- a/action.yml +++ b/action.yml @@ -125,4 +125,4 @@ runs: DEV_IMAGE: ${{ inputs.dev-image }} ENABLE_IMAGE_PUSH: true ENABLE_MULTIARCH_BUILD: true - IMAGE_POSTFIX: ${{ github.ref != format('refs/heads/{0}', github.event.repository.default_branch) && "_${{ steps.slugify-ref-name.outputs.slug }}_ci" || "" }} + IMAGE_POSTFIX: ${{ github.ref != format('refs/heads/{0}', github.event.repository.default_branch) && '_${{ steps.slugify-ref-name.outputs.slug }}_ci' || '' }} diff --git a/scripts/ci.sh b/scripts/ci.sh index cd6be14..1c40437 100755 --- a/scripts/ci.sh +++ b/scripts/ci.sh @@ -16,13 +16,13 @@ require_var "IMAGE" DEV_IMAGE="${DEV_IMAGE:-${IMAGE}-dev}" # TODO: what if IMAGE has no TAG? ENABLE_IMAGE_PUSH="${ENABLE_IMAGE_PUSH:-false}" ENABLE_MULTIARCH_BUILD="${ENABLE_MULTIARCH_BUILD:-false}" -IMAGE_POSTFIX="${IMAGE_POSTFIX:-"_ci"}" +IMAGE_POSTFIX="${IMAGE_POSTFIX:-""}" # write image name for industrial_ci to output # TODO: GitHub-only industrial_ci_image="${IMAGE}" [[ "${TARGET}" == *"dev"* ]] && industrial_ci_image="${DEV_IMAGE}" -industrial_ci_image="${industrial_ci_image}${IMAGE_POSTFIX}" +[[ -n "${IMAGE_POSTFIX}" ]] && industrial_ci_image="${industrial_ci_image}${IMAGE_POSTFIX}" [[ "${ENABLE_MULTIARCH_BUILD}" != "true" ]] && industrial_ci_image="${industrial_ci_image}-$(dpkg --print-architecture)" echo "INDUSTRIAL_CI_IMAGE=${industrial_ci_image}" >> "${GITHUB_OUTPUT}" From cc6e24b1e26273da54b362c51af072b2ee2942a4 Mon Sep 17 00:00:00 2001 From: Jean-Pierre Busch Date: Tue, 30 May 2023 11:39:52 +0200 Subject: [PATCH 074/159] format slug --- action.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/action.yml b/action.yml index e01f468..55ec6dc 100644 --- a/action.yml +++ b/action.yml @@ -125,4 +125,4 @@ runs: DEV_IMAGE: ${{ inputs.dev-image }} ENABLE_IMAGE_PUSH: true ENABLE_MULTIARCH_BUILD: true - IMAGE_POSTFIX: ${{ github.ref != format('refs/heads/{0}', github.event.repository.default_branch) && '_${{ steps.slugify-ref-name.outputs.slug }}_ci' || '' }} + IMAGE_POSTFIX: ${{ github.ref != format('refs/heads/{0}', github.event.repository.default_branch) && format('_{0}_ci', steps.slugify-ref-name.outputs.slug) || '' }} From cd8be920994611d1dcabfc5749519122e2ca1106 Mon Sep 17 00:00:00 2001 From: Jean-Pierre Busch Date: Tue, 30 May 2023 13:47:22 +0200 Subject: [PATCH 075/159] PAT is no longer needed --- action.yml | 6 ------ 1 file changed, 6 deletions(-) diff --git a/action.yml b/action.yml index 55ec6dc..af31bca 100644 --- a/action.yml +++ b/action.yml @@ -3,11 +3,6 @@ description: "docker-ros automatically builds development and deployment Docker inputs: - token: # TODO: remove, once repos are public - description: 'access token for cloning docker-ros' - required: true - default: '' - target: description: "Target stage of Dockerfile (comma-separated list) [dev|run]" default: "run" @@ -68,7 +63,6 @@ runs: with: repository: ika-rwth-aachen/docker-ros ref: feature/github-action # TODO: desired behavior? - token: ${{ inputs.token }} path: ${{ inputs.build-context }}/docker/docker-ros - name: Set up QEMU for architecture emulation From e43a3484e95c2f6871310221344241ad2028d5a0 Mon Sep 17 00:00:00 2001 From: Jean-Pierre Busch Date: Tue, 30 May 2023 14:01:47 +0200 Subject: [PATCH 076/159] only run qemu if not runner arch --- action.yml | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/action.yml b/action.yml index af31bca..0560e63 100644 --- a/action.yml +++ b/action.yml @@ -65,7 +65,12 @@ runs: ref: feature/github-action # TODO: desired behavior? path: ${{ inputs.build-context }}/docker/docker-ros + - name: test runner arch + run: echo "DPKG = $(dpkg --print-architecture) ; runner.arch = ${{ runner.arch }}" + shell: bash + - name: Set up QEMU for architecture emulation + if: ${{ !contains(inputs.platform, runner.arch) }} uses: docker/setup-qemu-action@v2 - name: Set up Docker buildx From b1d036c39f43f8e4f666f3f04ac734e39e8f5f52 Mon Sep 17 00:00:00 2001 From: Lennart Reiher Date: Tue, 30 May 2023 16:17:21 +0200 Subject: [PATCH 077/159] replace logo with midjourney generated one dark blue humanoid robot climbing into a turquoise shipping container, simplistic logo style, cartoon style, playful --- assets/logo-midjourney.png | Bin 0 -> 570729 bytes assets/logo.png | Bin 44317 -> 313815 bytes 2 files changed, 0 insertions(+), 0 deletions(-) create mode 100644 assets/logo-midjourney.png diff --git a/assets/logo-midjourney.png b/assets/logo-midjourney.png new file mode 100644 index 0000000000000000000000000000000000000000..c6bc81edfcb119b4c6b42f6a2674e3f8d3e13e3d GIT binary patch literal 570729 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

bcjO>OI#~p8lfK|?pW{~1c&B?4_MddJ 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%0AxZ&5fKf5 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 z zesVm%^`)a<{(AcA&z}#Ql9O9{?f(56ckk}AihCZ@ZaN>bC1gj$%tCjaZE2^y&16I} zGdJe#$TYepG|?IX|7V%L`2;oBU>9V~J6{lzG17HdGJy_NuO^L_x5MDYF>pszd3eHm z*uc=@_X2b|W@cquZ`HL2>Mzi(hHE8=U|l(Id1P=sp4u%q>kY1#T(22kT#w`*15aJQ zWj*WY^#FX)$jo2of7BOZ;h;U175egne$r6uQ+fE+n|#)o_c`U&LvEjSOML7YdT9aR z;~w|3SS}6O=Qrw4x(%+MUoSEAKhs%qb>Unin)%VImpBN$!2X^6(zS>iDs_6_ocg^Q zN$9g*dFCesOQfmC`j!|zeoaCV=Y2#o{GMN94hhoof(UIP3A`L_&*tL-(p_8dB6Oo8?j`01;jt{e{gE;_W)Oqrn9LOG1K% z9!LUCrIp5Q6`1rI9bo&9&5@9V3_)X{TxOJVfp2dd-FW@<;q>Ty$BW%`@0Y)h&FO=0 zeB=B_?`>>fE_R}`T7*a~7rR>b+N2+xJ@~WV{)>O^-}}$+-@o(v+i(8D*S`AouYc_; zzwmRnZr(b%aeTbpY{n7fRLaw*XAd7e`QW{G-+TXqZ~X0V{myTH`**+dy(eeq`}3*p zu|3&jrt^z^Eq-)*EKy1Dy@f8X&hzI}dtbVfK+vOFHK)M*djzIN}%+h6kI z9C-r_W<*t2Gip&v9<<3-LFr}2>2p@H>*vcQA$L`iD?hJpH9uyN*qh@Iv4%n*X|j1d zID&X$XQgbmu>z#@BH>Rzwym)K01H=_@nd9FqHGBd7zhaadEcU zj41(3rNGCVbsRUp_zSoHuHU!6dF$!XC?t&e<{S5pZr|A@+xt`jx`vz+C^=WnKbydM zUT%U`YXK=^+72Ad;bv@(=n;>XGm*YK#>Cl5 znQJ}5%dYP;d+C{8_18}i_BOb_a`V2laQ3bR_g5cyS@rYNU#>1OpUY1CQ&B$0HhAV( z`g8?=pWTk-Gd{n1<;O$+_`DSl>!)2^OdHN`>Mk5?4a@0`i;kJ_vff&;*vDV6KA%?U zxUJQPgb8I)A9+{(%rd}%qO>2^>e&1$?!Ih-ksyl8PRMq*)*77i0CWnk+Aiz>Aezx# z#-P^AOO+}!Y39{g>R>6G3oNx32NNmQ>Mh2RB06Em2a-!E1z?b>&lpeWG1t4`x1a`G z8hZ0a!LCCV=mMMsEGhgbB}N`8msI5-UVr;_um1R*54NXA?>~HU^XJ}p`}WO;zxCTs zzyJMYX)M$9e)QhM@4oZy|MzeFbtY{$1Iaw5Az99uwCcX! zm#I`Q)3mQBL^ZFLvQ<@DdiwC3FH*lSwK!o z$tzJU@y7AZw_mf<%|r)HF3YNui$;r%)8NDs<& z2q%mgK0~*j2QCRcVwQSFEO*gBRj6j9qs^VS-+Z*2>Vqe_%2L{)oD1C8$(QcGp8n9I zZ++|WcfT{HB=_9-F&fCTCl74MDW|0L-bWw(=)?EF`Q7jQr~l=DG3JzW-X3qpoQ6E) zoFwk|``vC|r@G%y({8GJ_X?PMExWp_`>E`!jdpr+e7@gDlS-(v>S9QsyYQjh>j~+kz-j8s$%eQW9zxMO#C|MW~ny6ri zY#b{cgfM#})7>qGCQVv25!Y#X7D*uLXEWzd4Tb}twU`A!BSapKwL>|wW9Wl(UK)Vt z%7^PtnV)g6%A${8tflbz9pl@)BuBf<8RhyDi8&1mE={f%n$(|Uzk0#d;-wZ99sd0! zE6ZnGUOm|M`M1Q?$9TH|m)z@5a zG<=aM_X3mhWJobY#6hIPKv?9>}Csg*o1hY(qI z%dS=I_2^TLlfJu~JLGZ)43q|Fs2FqJ!?XDgHFI!PbZ&R#5NOc^SAi?pfSdsJ zD220YK>K#7CAn6O&9AtKaNWYtI3#eY!mH8E<&uz?h9TX%d$T-w8I>to5PXLCe*Zk~wlp z=0?EWZ9gd`rZifjNH-~MeUo+jbo=&~ZvFCCbpQAw7$#H6M_bSoAscUOPT#zrZyswv zsmjU5A&c78$ubQlEJ7o?Jzy0P>lq{VV@C24i1lLz{0l7|*WcypQ7-??kg?UL8#&@z zOOPAMr)V8U#88;SZmo=srvTyTla4L!Oa`@AARFn)qtva8Nv%vNR2i}Stw;>m|k2{o3Bi)QXhDOFcWoc1N9Je^NwMmUg@ z4USq|8n&K?>F6lG{>E#6@K=Y|@1Ha8z~N}KH|E>NH(q}u-8k82ceueI8CkrNo|FS9 zwwW3_e-R3+T9Gr++^YjN4jfDtHWAR+;~WqSZ}rxKF)zZYW|pf-8s*WHt5M zHur-SL5IuzGK4;UuYFm87^_w1ndKUZcAlNf*Hx7^kl7ZTx;S5T5u9LS;8^Y#B}R) zINt0ek1WAPOUY;vO@(B*4zy4tQF(W{cR@fjbPX6=Ai=pBE6v%e%~}ftow>wYT8W~N=8vU06e^0KP}Tr}H?vS>(y+})fq!VK8$_cr95Ow~5SG0k?9i>Ls%8^3e1 zee<=OU;VP(yZMwAH0G3Oql1N&C`N6@8*kpf@%H_a0C>vWjzifOCd+1yS--d%MZ`RI z)|mO~Kz!~XUji;ZYs#;Luce3PkCz|z{KbF%WsP41=qm3^OL$y)0;(h?2c4cqZtvVW z{nGvsepDWvrKt`>-g~Kp58RVSUw-rFU%z+$o$o#T&Ube2e`sbZdkz3~KJBs%MXJ-j z)aniaDJ3%!<_^%2KvstUxv6+fN7=o!RflPsR8y`<9LN2U4R`L{|K+dQy?gc6@wqXj zF{f0D!}9jty`!JII{_8mRL77UnF+8!z+nSykun=HSC8;tffSvShtX0N;ixogFgm5C z^^mjka+Y3i)RyKI&}Mt29&l*D@^1msTIPKbpgY^$cL%0Pe-7tK)GN(~{_LU#ERq)ck z^JkIGsVlxc>lsAzhHoP8bEo5{QC<+%{WwtWS?j?U=zmpS1-SevCjxspiQ#9XyoeSJ zuSRdbQ2BiOu;~KVYMskZzl?I$$cCI1=KW%-$6j#v)UTbR-Yn1kRJvoe7aizkmZ_jc zcf+QUi<&RL01#;=R50x0O+VJ&wWIq8sY!J2-pf_#=KA?@0G3>p{iN7uI9H?*NzBYe zIo+LNQYPwg-cFAnJ^I!Ut?rKAxOd~LKR+H16(EtA(8Q0(lZwua<$ zexGyR9G^E`vc;;~q}UxmV7;87;HMLhB)T{lI+YkDR5<=avI80Nn-WvdI0s zn=B*sP;Q-%bg?x?gb>j=!&yZ#qPmi?Ocg{PhMRA^2Kpntn|59Oo&D&&C*S@4{{44xc9FdfDfzx^HY1@@L%=ftrPLT=kt-~jk-XULhcN?r z+EqYCi);^dJ7Cz9qm%sF-P>P%JKw&G)028MRI}o;!C)LW+goqGk>9wt8@xN%BPXjR zQVK*oO-Pb?2kDSeH8Q`s867^aV>TF5a+m-kBV(FZPnH1CECLF12A;izL(34!72Fq( z61t#TpPu7p3I3i@{wY@1L*RxR%M=53Qy7{tjB-ubrtY=Fw+W zrG0pAQ@m_b>B`ra27@no{_nl=xwX)9IzKO`d{I7GnOpZ`=h#}$^)p+pMa0iIrxzVI z;N@*ZYXfwsx#qK5fRyEA^bBDQsdOFBI)46h^elMcweq^tmIGvS=mQ(uKYUl0%e3+V zSYNzoq*i-FyZ{}uL=dR?P%vuMYM7oqL&AC^S#eM!<(ELfs8VSepc%YWI4on@PfD~> z{P7c>pYNgc_LoL(p4KuLy;c}HEr;%&dbphC3>-CRgalfG!<)aOLU?OExC+2NcWi63 z6^2o`Da2Ln>@Eke0M#=on%BylWIVoe`@ZXazB4^O11udMU!3o8H15DW-o1VQPTpTk zKX~`a58k=>=zZ;WC>Y$}70h`sfYW|5%PAWZC9)a`OL^RGy!!dsWJAXG$jx@7ogQz# zba!*-?&eFc>3BO0sg71?wbqmqg-n~K!T}{E+&H@VbFUxWzf}iTx(x}S!D) zfAYlrtU9eam;oP$49FdDI6Ng2B2Tr3@dz}@)41K2qH(C%Y`Y!q-OM-c9KZFJ-MCqf zH@+DsvbdOy8(!3!H^a&6x9|MIn`Z;61%4+hyn4v>5#}g{Hdl?*!xXrgN;pMGDVy&n zGb7F2Hz|ABl{#S;9}U^8;+8c^m95&2x){FYUayti_&wu*K~6 z#S^rt$I-}9tDPxm2Ymr%)1f!U#JB!>7E7%;ynB77`pE%4Fb)(vtNh-zJ%pKBQiBmBezftcMdU| z)5Ql5 zp1k{RefVVe@DcX4c+H>^YD8{|{0TW_SOF`+&5({a`+j0}i(1!DK{vxv0a zf%e4~;$_-hLhM?d z?|nZJ+6z?*O3#qXzU~Z;bdfQ<@!E~o?%l1wy8Gba(+}SBhmUs;9{BkVr4+ATYIwA} zG|>f1WOY$QO3JBjHgyLBjjxU_p_KEbA&Pftt|otH*MZ7w2`+8s;6)bK z>t0@$KWN^#*kW<4e_X_u+2^jI_D;_3ruP21?|<#%ED|&hPYbo#qAAK_uNEK|VOG5S_{DHN*f!IcK}NDi(QrJVzMgB^imB>mU_d=%sd2)l>!V9To5Rz ziUxQ~%WseJ{liDP*iC2W`=@8+>|Dj+uG%^# zAtT#(vQ^HTo2Ti-C(ob8_!gjGK|IDvaw24M%F!CvH{o(~d$T6U zKtlpqU@}2W?In|$SJ~|IJwpa!B{cKW*n94*Bs%Be`qM7`c6H`Gt1HSvwkT z?GC^&ASrx9r4%udEbVKBd)}m5U%GdEynXj~zkB}SqtO#xgAHX@Ee%Zc;$ERG9ZFSs z+}?Qe^<0b2&-YIr*YgYC@Aps7y;KyhE{mLGVj?$3TTf{?J=M`R-8k{>$fJ`w*m*_) zYqp5dlR%N~wYco$=+0N(JbwM2Z^vCm_S}RRk6GP<^*58&H7gujn&~bmz&!-}G!7{b z>M_yG%uLk`W+3ZSb4o4x&&oYl2)}$0Zk7m0E~j+$oiCP>wX~aJgWvTSAKldakW1B+gD?h-*4 z4t%X<%sVShFSq?#-T9)gbLG5i`m;5VmN?w2hxc7;mD2#2HAf5g^Rm9Q3qM^j=sODM z##lC}u3(!VwhGSE{?Z~ZSM0i~)n!Rib@%G1$tqHUfpAx?np{)Kv_z{-J>R94xs5w6 zUsQV@8Op*s;A|>G2Su5h%+Q*vDf!V3x-^w)WM(^9y;?W%1O`!XnIJI%EM5sGnNp&- zFEyn+-n#YLm(#=Xz1;^Nu{a7`KuSYSnmA26O9M83K@mvf?Ey@}3F%XXd!U|3cxJLf z)=iQb5(CyPf6Lqmm#aTv-}O-iI!XC5juw!_UgUpxKMeQt*q@=2t_AbOK&6oK$v zn5ofodZiBFFCp`nDVK>9mv8i(+r7|})|2U()8b=fiFt8R1x#MWN|?bSG-XOAnAfV5 zx3_M+_EmngefR9$2jgU33Yk=@s*^U1qkxO47+`}2Bi!=Q1~*QPHqypv@>(g#VWLFQ ziZg8oq~wVXcm@aC7r9WXTTZ3cVaO(^RtPn7ynXxl{@s%|@A}A^+^Z6kB{jDd(mIHZ zHEJdf5dzsrQX*kJYO2)6Mf9iozucre&TAV`yn966;3P3}{LG~`_C z{`~x@>STtT5|XJFQ=krmS2g>C)68qlHs?9(tuJ`6lN(y^p+Eu$VBY&pbVzi!WUwUD z`EHjI(`GP`?!~Lqn1G@?!rfC`w=Ynb#N1 z;_G!k&i^j5?V=)gM*1*N>0RZryzUJMZ93$%VZqGYQ27v%J|v7|h~w zS|wyju4IXMkSm!1pc6>QR)xL9oSbs0<+R?=t8&VcHfgi3Q&JUChII4I*Y14zEgWs? zP^&6nDQCG*2BjE*9FPkXV1NiDl{?x|yRWW$=d5)K`l1Z>k z&z|(~>Rq(@|CQ&(tiSG;=kxH>V{xPPq|`^?Ja z+kckN`tjDGSq~`As+4&voZ;?4;K~{K%xf&?eFa^w607N~AmzH2%?5qI0-8VY@be{I z)AILY%1X1--e7%zvsrwlw3;`MaI{;9J}Y9-!OdF`Jsr^OXGPd0`qaY4*GfQYfRp`( z-n8?SyO8MaD%Dg=t#DDOWpejge1Eaql*(a6Vdx6HCcwc%?C5gK?B^__wV;n32SsOu z6Q&WWFwu+ey)|$-H zW;l8M?r?PUV9YIB^Jrt{s8TUs5`7TMwYm zMN{^?c$4+f|zk}#A>$jLUt(Y-tOEIobyqv`RPW!9;B zt=3?-pc?X4-WUWk^G2{SuO983ElU*Ka)PtUMWjrZNvcpvS#FS$w_x4IV2Z?fdj%|^GkAOuN*W|Tb_JLG{qh)3!vq3l&J|5kUN+RDG6|SOlhtC zaN=Ph7|UDw4AA9d@Xpx$hCx@YQ)MX$j#_u;=Tt=tO_YjPhZqruXtK~_#|lEwR_n49 zorD?oE4+`}kFmx@r_RgV9CQ?lh(^oEI9Q9y`RIaYepNatRdlmVwcdx5$@ROJ%pJz|J zs0OIgczmqZn` zu-EZm%!oH)|8(>|E06%f6{==)kEoh!jaa{L-#q(OYsqriGJ^^ndg}(aS}>5*zyWC~ zk=>pW^$TEBUA0E0q`}f=vRvYEFr;*LzL#7%lSpYuFrd0T!2mB_;p|M2ctj=1lmrRf ztB%`o7{|@g_~hillMg=h^NVtU3??R2fPfR(8e4&2GDt4Dkc<(@Me-^*Vaa4rl`2Hr z*TO^xnCJx4hU0K_>-6~Ut>b&QkuWugX4w+RAYNn6ZqY`|ESMb*thMy|g4?jxXMaxR zaDrdEAZY~|7YQZuI+|uwZRT}#K(tQN-#Sw7wL3!|Lw0H z-??KaLp3X??v9klykTJAHV7lEJ!n1A$1HlQ_k2(J8%pz-ifrLBO{hqgHzSOq12PiU zJ%o%tdE<%^FnS5AgWQXyCXp_zKhP!0hBQQNg5aOYxi*WsWb&OaSwm4A4DVUKda;3e z=|+bm^soq#!(i^cwo}aHs(F*b`a@glh3@~+gR`yP|I%Z0sR~-3{IYxewU>N?_23J{ z|Fc-Wpa6ZA<>~_Svo9+>Yn^!3o6k{SLOIs;*;tcARZXeqf z^WO530BSkiAfe-5%^TbD3JdFL74YB8%DjPGspZ0{y;L=Y4_aK;h`LaJMtelV0RU); z)^zchGjd7zbN87t^e(Chio&Dn{4?p;*JU%NIlaVRsAeksM%>mkEDOpZXfdob3C<7^j zX)^KVf&lZ7if0PCi3SuekjBke>m*l6U>;6i zyMJ_YdiLP)qX!>px6^rHMXg0u*(jk_z+n(9V(NntaJ3R-B&Di?rLfTuVR?c;>@nrz z&HejtZg1ZjZk%Ya3JGoqLy#rFKzD(lB}Z^w7zV0N^_Zjo#9WxC@FL-NC3=JWc{6GW z@6%{OX11DFU1cE&iu8O9OvZaO{lY8>0Pbp9c?~HImTUETv8%g1B%ujONZ@eJN{8O(YXrk$>jczoOA=t14$LhV_*^yp}_Did=tD!^1(WgP_ha*yerq znWMWeJUE;Ls|$K7UA@PA<8?r`^_|z+qM6|qc^DU4C>FbId)?4Dto0?!{pK;U!tl$b zFI+w?$nm+V5xyv&Q~5#w_%X`$+Jh^{pLN>LW_i{+!PVb(;ta`Gu(*i<2PdwSEz6$F zhJ_o^eZFAT?2$IB*_6XGZuRpEcF1$iIebrD{?<`HEX5XRv2i!`r{wV1gWJ7gPxWq9 z@0%%XF=QONkj-rp$vzhYHCq0x*`LncNo%f$q>Pe>xJ6?!tEI*Rli75(+dq0T-aIYv z3YF@$l*Zq$4pqp^4DL;Uks@ZuDtYaya}}ab1Pl$?PAw7;oYn&1?5Dk(9o@RIuM>01 zq+fWh@LjcJ0}a$@$>ryDa(O8*OJg2=^3js$$Vs9lbN4D&>LClKnhYr?caSV)p8;$* zZpY2>o$kjtOf$Z9}0T-Kx5R=!~BFV}48k1rlR-akDr z7sevFQ!MTT5|g9|6%_$BGdnLR$r8PJt-DAi)}&!O-oJl;dwhC&YvVax7z%30mzf5! zvUi= z?w$@b0tjAVm>FiE>5&H6g<6?2Kuy);bnMQ~FP=QzxRdbWMuIJQSsF*ngDmDQcg&sNk4|&1ZGPB@n_)PF=?MeBX78UGt7hPhPF@i(`pv@ySb_ z|3&!>$}7>ve4YUCO71PMTDcbMH?-Q%x%BmCw_JiGhkBc5ygygm9L{HQUdsWjXb}Wf za6e4UmgaM~=7!E6p0Oz$s#ZS!)mBwr4z3<`5YVBo^06@_fZbu#gRLaNjFuXMwryiw z&O!5z=vzkDlyz=>W7*FwqrgsFs<+bm_qL3io5f8?GwZ2*z4bv*1XyZ4J4>~|T`6sj zkMm}uCugp@-|bbzk=1L%v#!-+yWk?9X<9y?Iq%Ow1r}g{GZ`nJk|kQ^Ci|{T`~8sY z#>T8d`)akOOozMsFpL*<%6YUzuT@YsCYL*E%WoiW`Bu5tzB4Ak68Bl22ON&(+Y>##d1;Y%4Hdu@+hw|s|Fj6Pqs&=ckk`b z_KzPv+@D`?f8iI7GSSHzkByj@iDpfzGm6!L0;L3w19INnI61j(CI^}}0=phXo;O45~E8>&^6bvj4u!ff}8=7t^e?f^ZpvsjHrZ!VbX)_>EP)Zh_ zIsn6l6a;_xB4IXbLnEiek!l@r%EJ#B$xK5oRSI)L0VXd`&XYGMdo#LVOw}Dj%Ew0- z2Q-JDrr2(4NL!!|hE-p$y6mh?h5`FUi^j-!2Ve7Iz!sU)eto2h_azJbUOZ zlkA{0DRWs+uR7$ehw8H6uBD#kwxNFMk~-JTq809+|Gg%c<7F9Ssp%&y^Y;48#`yy5 zect62k+Ys706cS>_^kJjpR%$BuUB!RR$pI*4*x96B}k&HKOU9GA(DOM8FZRBN@7%r$^DbaLjK;FnYki^Cq6mZD z3#@cz*FCq>YD04tN;Q{y`uJ$Qz)V6H8`Ok^c$}pKg2pg8P?8I@OxAsU^v=6Cf9}nE zya8<3ZjlnqGC1T!8flh-($G8sUEa|L5D>q=ndIGY(fL9UWKHxyHRE7*ez9ZrdQn_L zL8cOR!`XCav;ETTyLWHidgswczw`cwdrq6dCV3^8urGCsG}T&Nleq+Q8qML=mGfW~ zDh0+?ZJN0oT}&0p;mnjMOB{7{x-o}Od*4r9>c!bvo%VGqrM5t$0!TyhycuQO3`5?I z!+4y=WGRDmI1(MAB7ZAANZU?|9s@fC=n>5-YRIh(B+S%kb-&HI&pS54B~*XSa?Cb| z){@zEhA19baMgba3??;l3Bub+;GU-qs?%%8O9?Uk|iox zbuV7BS+-OW+%q^SFu|%jNqXe8bI_z3;zvwf{?O^_@lGwybKub$1)cDp@3$`Xn{dG~{I zw%-t??1z*fhoRJ3oF_L=ZM&HuB&*d8G@939w3Y_|Se5|vWnu1i&3X|mGC*4u!a|9* z!XF5@^N?v9>N7@fAMMX%o*i&^8mp+oaI8k%dXydDlR_g+S@HdY2m6N) z^U0eqa2O^q%bmi$*pNzfCb}vCGYeH%XZ7eZ{?n}V?nk2XBW_&XPO9zK2gBcHr_m6%KpB2|Ieyf|QkrGaTz_sI-k-B)+d zIYG&&G8H0Ms=CX}8S+pC;gGXNL?0VcK290=rfwMocd5mLL~~sTvJ?sPmgqP_GlH_j z6bR70g!d>6ISsYehV-43d-y-V!Y>mm^G3jEyF$XzR8;0>ym>O@}~iCZ%CR(T5*?vjA~>y!_nsSXw<0* z=0L$z_6;nPku^6N0OmZ%0E0s!NxHWPq$y>Pbt-gbqe^J~F?k(_#6&L=DViuU0iphv z(=C+tO@L`D7|_yTEtEzWBPxL4uIg^XAhYI#Y8hh6gQYY9$*jAl0P#;_;LBh_@mduz zd>o|FD6j(g^z?E1P-A}M?YF#0=lkiSN7I8xn5Hxg1)AyvFr{oMYfQuGN$vd1+0=kW z_wP#lHnDp@N}a&iyW5EBi^oF4`JA_i83>a>othJ2w^N?U-PG0bwv<^G?#uM$b2b0W z^(BX+vTIisE?@t3QM|-N7Q12e;6eRG))6WCm51WM)y?#13w{r!7)?)r92oAJi$Z#+3W3j|b| zm<*`2B(T;x5~RW5jgG)Y-zKT;_fohsEV2?zsuC=fQpPc>VgruV6KZ~V{`2>4{E=Vz z(y!fr8!Oj7rL0b)|AZ7{WI{l zF6qw8tOK3?!iLldOAa%0QgTPNGz-IWhsy(*8EBa)TegJS5ZFS*A}NGu7wzjN5vVdG z_gVoajBO&xjGpL~CBbU}m@Mr|Nn^}v52K$ax|plcn?FEJ@IJc*hIxR1;9vqJYwJcD z2D3~UP(>jTiOl9uHpaYLc^Ad>WA|Z60%(XN(*oS6?Z7*?@!;{v?c4W${%s6f-|yc4 z_V3omXM5H-oQP(Zd`5o7iis2 z8Eip8z5g~(f!RM~S^k?a*~iVSD>@j9&%`n9fjn57`_0w}{nBl&Z02p-;XHi$UD-)X zi}?eyQ$VjRm$zAMXqs=gs@3JEzI6H719U%oZ}jPx=e5x%w*Y*BX)l+L-}`5VJzjn&A4ngo=!}hJ!glm;J zsJ8_B_GUzpXh|-g_M_!-@>A*U8#n*{uYTnZ+`o5wGFF}C^x#P;lmih&M3n=^jfQ>Q z@39|-fuK3DpA5c9<^&2HLO2Bn)?y;e-96qJK>&+DbiXDCTy#sB4o&+hC9@$5np`Sw zOkqDU$;{x$2_|!QuLyMNss^^yzl2XEkPBf!1ZoV2Mi-AjFq|DXW)`*Dh?p5%YP7c1 z0PZ8G<6|vo3JX&HoXQ%xj{7eIkr#p@5_og)Ea6?!_KiuH-Jtl9{|z$}9syDPE}r z8O<_8O_ib{!H@IRBAa%&-Ttob$|Sox9+|D*0Iu%b3Nbv=$qeu^3Hp*4ARIcI?Ij|R&3&%*usB5Ilq=DyN(&t{4-qpox>V03 z68eOcc*zH58DT9}R(xGK87)ula&kX;KCNxmmlpEX#ny=2qy6bB5y7b7^S3djK7b@4h*H1HKd08;>ML8^=#0LP^Eb(8IXBVy4tlvw8S3X?% zrj_mum%x4dc?k*>BpKSF-&Fru%MyF=tF7?(r?pxf3N5X62P~k@MQuKCafz$HTGMKE z4t?|2Qv{%IL~siNgahG}=kbC8+&L?o*4th~P_v*Bw1_31hI(+7me#g`t46Mf?N_9H z%XI$e?1SI_#>wgNaP!V^wZ74c(quGOZF;-rizv{7 zW)y8>un7I0%;c0$Ii=B%&vtJfo&1A;;8%bDjg!-YP0kN6{la zlu{Cz&FcAnOhz0{rKncOj?=Jp@NCC|jU|ygO*RbGDNEB-%QPurlL?qy?p0>najaga zeMu>ed6awISIY(=rDQ?eh`5oW%Y9!7FeRPO$sX`X| z%-Q=@9Uco7{-O$Y%d8wMeB_|Xx8I*QFtC;kXeIz>HOs+ za*l34U){abn=IVvXI(Om>tcv5NU5uJXRnnus{;@(t^nlh=Hfl8Tvxmpjj9TN4NDeY z;c; zBR`p3wzKY znV0IrjgzC-?(R1>RUaZSa9g{YZ7;^>;_bQ`2$)aqqtsPF_KbNzBnFV1=+!M73gF%xd)(Nx+?rGu0*!nnTDzGy?RYzLG(^hi_NSEE~d=ogtD^;NXUR_;-V<7D=Q} z2d)pX$4hEmv`nX{+B4*bE6+T5_?54G_6ffS$`|PW$17ii0sV~2Pf9|46(+{=?$4;r zOc!O>*36sW{I!FL)osHMIPmTAfQ|#84s_73ZbAm1(|Ppd6sL0_w_D8Nehep6F7 zc563+2Hb&IfSd@Z-`sggo0f=xwi1w9>>mPVwnB~Fub?5Qu5q%tN!m8u^v-55!N_C* zsahzHS|!jx7^{uQyARL4^H=`b+kfy6*mm$?)X|11ot^Ep$$69NZZE(R#M;u@&P;d( zq9H(e5VJ#L8;L<1*d+o_2XPrgO1YNTk2insFa6@zZ=BvN8fjGJ$Gb>OPo}IhMVVWC%LK*C-p`6XdxuG?qlt|DZcx@h^N@L#C$UKmYlzXAU%mgo9 z8J$L$QDk)i)giOUbJaS_1xF=<+#ac97or$?2DKIT3k!g{dJ_#ydK;JXcwK19n3bR_ zzxXyhRzRu`?)BX0%2Rfpi72*&5*@^MyIc(7HWEE#RyhS4eXi3SICk|sc8KS$1R5#8 z5w;{}_|*1FhFeYKg#ck8LOBGAl*=JUHG-8y@+x^HT|LBZi`uUqIGD;b%23gxw3>?3 ztE+B@A(0ujff8*HbWxI=_59)E$4HvWG!DG+`n{tYCpGKg?&*`MmONIb3c;!b(BPn2 zpxPEECl&>V!MrnG9CC_7mNl{8QkFFWU$~M(ij3XtvF9C5Sq7alCSy&sOl1N4>hcXq zmufwK@c4tj^Npw9`~GHE&7m?eAth6FkW+OW=k4ov>d`PItJNFtDP${a(7*QvyIx|w zI<5ptk!D_s(EyLts_72A=_%x{YSY=iT;+}ExB>nODGq>lV!V)exqppm|!^|VL_^YYup+GTue?JC_xhF0_L0<<*S zHFdk@*o&2`(*I9yxhesDQC_lqCIZ0k=}vhSWb)6v^;cSz7drhAe9xa}jDL78h*hK< zbR|C}rDT3^85`k7jTo~uHaRoqSJ73jeU}${k;^^VbwPa_!lk`Mvl*ay?!t^HVc`ae z7QMUkd;lZOy)vyDYBB1gYnTo#$e6L60+ua;lWV?jDC8O&T3%`$Acx#5K!RR9WmA>W zru{^dW#qleN9RBM_20UA@#M~zzpPE#+&*<1&i5CZI9eKqbT;k7b$Mw8LGE2PYa5?j z%nil?Ko462fsmzC+)L4RDmP9xzjXWNJ+th!j{Mv2fAF7vD$ob)Kee-wz{9mfyc?Tand7x|*a`Me^eE0V8Yxi`t8E&0!Z{FD6 zx-lM|3@1n1<8gcQ#FN=LI8mlrT~%_(895mO0z`kBLMSkcp=AgM2)P7zG}f7mVlqJy z0x}2VK?2|g1@seBgpoJ0`5E`@acDpw839JNF*$s4GaJmjs;W4^oD$7Mx~g1qOV%KS zueG1u#aNA_#s%Q04X#GuUi%(LABv0WbXLLli7L?vw%|N1^sRvA%8J0{jVB-Z_PadB?c=-68ckAQx-Q&kk zA3Z6ypK2Ly9siI1XMg-3{%`!TM`ic7-+Sk8{_y>erjkcPf>W@dEA>g+#k2-v35urh zB=Tg&1Sf4sVJ|EYavqPj%q+EREW0Y;i<-n?OsbV+0_D(zdNHNFpSoGG-Bgc^>0EsD z=-t2lt&4Zx)D4N+L(^)COpGN#7ZTOIT^Xz@6Ct^h~#}`o7MIr ztg9GiqePQ(8I!r!Z~a>=OY?fZ2*8J!c~lJhL z$n}@ihO_?rvY6{9f=fQt@-u<{f8yQn34H+OiSyD|{)`o^2I8}H37>x_e;yO#1s@Pl z_$tg_z{R3#Yz%=*^3zOj4bAKlVIh8t(>g-K47cYjU=6QaTZ#E`FVII?e^?YaP1zMl zB^3Vz)zS<_CP<5vz5E`8Bf)?Q9M!KW7ccIRAhp-@0B zOKdw+sE8HqCAMglW`i*sO7S`+njD}?y~txmC5pCVa^m8{$M65m-+KDaySKmkB1PrLw;vt3}od8M#=tJ>aV?LD+brS5O zQvUL{zxloWMLjvaa77c2!&qxAm6r2`OK?k;s?uI3h2Q_}->v_@-?ED`>`E?Dt=ZDv zYx&-L5A!!`wtRY&HluPz&g0GF;q(NXF`pdg6D$P_T<-1> zPqYaS$;?1=N}g=6h8vmMh!j&+SPzypsg0;mcsD-SjCf`kw4Nk~Gv#2BYf!5poUW%1 z9!===5hkgSJQpVxfC!F$%;gsTcRe`;(a@7CHwP2Ub6P!oCX|z@NBuHFFcW;LN(xsH zqa~)YFQR9&>`9ZPs_Nr749F%Vck{-`r^~9ddU6uAp6`5`_7}V9e0O$sF+F*D{?X&< z>EpA9kEf?k%agNmemb-o`()FOv%u^DoHxVit)<6mN~$LaOAfBxa4v$Ka! z3$PEt*j0VX%#;+Gs4N?%~ibW;oE#ETMLuu&>kmA3T0~zW?xaym4}T z_wLb+<7x!CFU6@LnWd!g!tiPd*+w`fceeGFbq){R=L>Xp|ZivaXytHTS4UkiMh zPoI4NR@$yPL`#PgP3jO_%CQHuT$Q1;T33QifBx*=VOJZiujrr9;4~1fc%}$?X9W(h zx*CTk&aSe?oNaOB(99Q_UpRhM_(!r6v(=!x7Gr|-*A$H&3bqz4bY@lCiZlnH!`hPcAsAR>*70 z5w(fkAkcQb#!l|84ho3~6%oLlmMM2<&Xy$G4|zy{B~HlSfB5iQj~(QtH}wwt`&@Lvfrnv?4Dj|+Lw#{bg`SBp6}1j_fMYgFV4%^{^IG=axwXC=aXZau&?G7 z1tw3GlxMGlxrua7&RX`&i95(O?s2?3JKdcb2OGyPot}Q<@nbJ#*bb#mkd#nZlaE3{ z_lt>cb2%F$FxplCEoU?bg;cAjA*XSu63rTUEQ~MFW=5e3s0Mi@G+5rBmxtf};rZjU z0zG|r?iUxjxX8Pbiclsaj8@@ZT~?VgKp8y`kEG)}daQqvH|C2O(72oFWWth;H- zcr_ZBH?BL)=JlMl57UZgBDqN<*qKe@Qb4<1cV&xe~gZrs0q%`yWmTB6qAfGi;um14z;NzzP-u+ZaDKAidvhVQ; z1%RKG#{V?RO56GIr+vm1!ROd7FD+&CMQd4L(bvm3yfT;`yu}Ke7$azU$CqeoNSn2V zj952K_tlr(dCk76+`MvhhDFzFUS=|Nz@QW$$keP2L^~pgOx^c0B!r&Zbk>1&vS@!9 zbe$Q|L;P5WTnL9|IfU4X)MH2XDt1kpTCho|9|}@=7qDm%tsHF+?jbo^5*|Zvf#5D; z%sI*H-ltuu`;VTy`|#;+e;WzOSe~5c{oVv3B}cNM^Gcd;0LC$8fIPb>?kSt4M4&}I)Ai8i6VlXl{Q$YWrQ zc;U1V{E!mO%mKL!sMRg#Xte?|dek-Sbq1s^)fy;Agx@rq-@MPNP~DcQ;!sVFB%r$Q zCNIUO;#2YcR4;b>rx$gari-0V`|0d_e|Dk$-uHX$cDpBMET!y=mr{3=O2Jf7DqIGr zNbXsdTp3IRfm-&-Qp*7yz8s~Z2=0^(Xnyg#^Wx@1@l#7?ws&kM&+aMNwD*(~=#e3- zrG`_3`^~t?PS0|XCW2-*B+ingi%g=?QmqxKk;b~ixH^%D2$uj-@>H?=(MRX+Kdcbl z;GX4~hz#4HS;Pqii*=_Qnv%&ZC`I8G-2ZRQ_}RU@7Z2}w300r-U6auUo6iuKU?)Af zWD)KakZ5MGx}T;}r`^O49z6ZSvDiq4;<@-c1nV_E=yDu&5tUtWA5{I#5k_V1!K zg%%^&AVI*W+UQBi48?1iYOU6YqrM`1n}R=$*ibRQRq!7ekZy9WU|BQ;=f-O8moi#i z?v2?mb5>Usuj;_Oze;!HtV$_G+90@VH-+crCK)HGmU6zUawSW(CNY_LMJ>n!A~;}! zA!cx(My9MlH(fv7!XCnEYcz{|NoMYl=nglW@5@fLBJFCW4Js5cVe(Yn5PD@7DVE6x z!CjkiV=0+Hp;U)!%!Ueq)5Vm`l0_&b(2_%CSHkaNlaflAd~!od*+@wv6LwS+p28=a zl4Qw=J%~h4!7ddTTYe- zrfg$M+mV^1*^rr%Sz15UNu`t@LUl zs$#B=tzBeBb}^d(ybwq!xmP%jEKvkgtzK#oWtrI$n2kxr>*RH+!|`x(yva(KY8r=3 z3}BMNSvPvfEJA|1)Ja(Y0c#``2`M0bEOh{wC^94+m<8#o83$t`cfXJ5C4)@na+3o- zFuS`Kr8fDHATv&yEJ?LSpwuwogzYJes38XmWU{ubx#khl^$&erRbP|PyiVL5q`bdI zC!BTQ+tz<$au*CHQs&i*m(jAp_B*e;i>DX+C+~kWo}QfCxpnKcd->!j$82tC%yY~XK7y+ zfexh`$moly+%H|wfPP##>-M{%iG3wC8nh(kLL9wZ)<3O29Ppw0=lHi9t{bZc==@ay zv$trfa)ZNRG&5*&RV9%X36aCdgXJ(l%*u4nRSzgc7nOpDF;DL8Y~<^%zazciK5+ ziuYm{MVl&=peas-RTpvsQKGL%SX0e1nT#+Zj2M<8uPqXo%&diemoblnrJRNgGth?Z zz?7KG9m8g@ae$dwhMA>AOFhk7b2HLn(Vb|Dn8X(su8tTmFn(r_fox9#I;jZtzIf6l&V@)U0&g# zagT5@wN==iwN1~Y2rTR20;GzZSW8JMGO-DYAWI~W@*qHy3vQ$)heD7F%{)PJDj{qZ z)X=umIOH5!cX!EMVH~m~5RO`X9P*HJG8izV7Ax0iU|SOwnTerBuo!1z6&+|fzywB~ z4jb|m56|Ywn5;;a3{e61z?ETROfrvEg)~bpK z{KpvQfLC`S%@Uu@EBNfKu~KrgleI#8?!>dUTw3tE9GyAet;S0n3Fq;3bVO4{ZFsh951fvQqWDOi)6bpeQDWDE^QSt z=Np4*ru)x(O-zdZRIOI=z8qpTM-KOvzA`V5?boj=)?51JG4J~3KXZWX3mM?YD_>Xu zKHu_6Pr#3zNzXygA9vk#XU)`iF6(t1>FZ@EwHG}mr5Zi}9m#6;ew|NS*V5N3X9LLS zi|lni42zoQ>iaI$jk{@ekHAFDDN+V7C3APVhxej6QWafwzmGhZA-S+G_1%0yxf^rb z-(sI~F!cb70KgvDr|G|X-DVMj?rtfu$4%*bOuK_ijP#o`Kej6;o13QBxHhLu7r`+P zf{dnG2~{tfVIWz(5;o)N*C?l!1b^nz-bpc#E84fEystn8^ep z0s^rSs`?NiLWCh2u_{D?PA>?yPL*R0CFn(h*ljZ1O+#^`uHy~aZFYrk{|2mZS{3$z zI0>duBzmo$lC=OrjqickSkY?C&eUilw+pq)=*4`(N+Y_OJBO1?5?1Z8o+H6$itKMe zR09-2`&B(+R$BPNDBMQ7t&9ET14}h$&CpeMO)SIFRA`(Tb-$M&mULZubwNxGI#V!n z_Pk)tyhbMEX*U5#Ovwg>>qUsHiP22qz^{hI=f;D((@<;8DHD{*s}Gjx?q1CDI1V%# zkS%qk03u*)lh}QhBfDpROorb05%se*bRu&L9}FW0W6lcK`yNq?Z2EsRfwg5yXx-xl zAPU(%g#fu%4kn3Ad#~K&?eQ_a?$0hF{HaS!hL8ec)mj#f5aqQD){c1>4Yx!y)ey$o z5=YY2O{A&&0UI4H>TAfPCd-y;ExxZZrZEk95Kt!HJ$Q8S_{ns3mXAL=y?<*sI^G^{ zH{0#5xMiv(;-CeAD&|#JyZ6b}YRdUV;$OAcK?_%>wI}BZ&|bDjSD2^8dK&Z=?o&wf ztT{yb%jelq2g{YbeA)|_Wxsos0mqM34x8_%QVe(ns{P5sfO0h#z9=tIUd1+>SBjS! zk1scPuRr@h-!gv*>S5sq$)!_~sSQCIOCE)5-5&)}z@%!89wtM3Zpw?(^G zLZS2NQLtAyDcrT1PS^u{xYJ>xISiiYKJ6ZU_~gO+AJj5sX0J8oP}fW`(19h^<@v3; zjWHv2`bxK;8v{wSiYx+7uWLhAeY5KOSl`GSC&x&ax9}JUA;H}uz@yLf;%V=eqbnk6 z5Xw|jLSjZZ0DEmfZf0dw52n-7+;bbx`xHZtafeDo^X^1)wg{Vq=qf!SS~Ob=E>cx# zRt=RHPqwxlVds(fx758?CoShxOED((?c4xSDbZjqH7dJkmS$(^Y$G7Sy?R#^&YXZY zXpPp=KB%*?dUmWif+bVx{jBixX6W_}21FufQG`j6WjW+9c6kE^kw&W4646M^EZ&4g z2o0wzAa4VbF&-C%V;lKbfyLrTvP{J;llN2G%?{@ABJ`~8)xNnm(IzPVQIV9gBzbMM zB17Vx&3Vg%rNxyzq-6zgWY{y@d$m#^JW7b>Y^#R@K8rqq#^u#5r_leq*TF`@Ak|Vs zETlkK>u%B=T`G^DJ7K-6W+GBzc2%#91>+PmEoYJ`8=we7+M87&cZc<_1&?Vlvl=S* zh%6I9VUe0m1!BsUa&rKHSsLZClqxI3;Wc`Vl)EhApvp|uogS3Pgh1G-yTwMxt_c2R zDA4xy>D@Qpdic>tyWQTy6&Yj;Wkz6mmq;osm1ddjql#Qf>B9(gIh1KS_Dn zD_?LyIedWyk+UI##F^5g?iV#*7D~Q(UACr*ZC~3R17j_;2F%Be)a(UtO;a|_B4?D* zNDfWSJXeNoI}>`6m#Bxw4jyZ}wI>_kwbGHGtozMH zk}rmRBcg8;$d;;C0An5^R3(T~iX~$w0f&Yj)nnI_Iz3qk`#^Y3m%yvBXIrYm6t;hu z1h4YaQkj-S0Up;@8NEWa!DQ4bnWb@X_bLsR5=^xbVBBRX0gZ7nBjKP<&>$qvW0FSD zXtkDTZ0mf7pp8dX)7~9EL9nvm#~?Kw6@?yMzc76CTzy)apPbEC+iBh@=LYa=E-qY-WiGVD-s@SS0|7G*urb5k9|K=pCYQT5opC2IhS#qBe)j(FBEAQH6yf)kW<-<+R%O`o}{W-fCXrGcT*v z;Z-cXHD4{9t<~Raf4wA*{iMr}nF#Ead5@op@(Bj($F}Y(ENeb%aI6i;GbrpZ16Zw< z4H>BU!mZC;C=F(@gL+feEtCLbXxY$=?5(V3;jFl6;rTmbwUcwuvSld+^&r&biuFBG zL8+pe=FKS-w_+8lvcYPd&i9W$_~`L_ADlmYVh)=;r-TYNy|AkWSwu9e9(lsNgDpo- z0>A^*)=*bG*S&OF_gW*Xu7O@tTiXx9Y*azSB%y^1U_%vACCEWl1Y9Ekc@^QVu5@+) z?ryY{vNHl(&U>PJ_#2Scp=#SbJ6~BnaydZ2oY>deQ+kp>N|t(@!3vMVUr8oR8vZFIzw?=C6N-UAxPlyLTTQVHTw)ofZ|#4TVpJARz?f;(RY1?@c>9E z_lm3kE+LX+H8V%tUxc%!6oV{a$=tW07jDXIM3~pGT96RD#Nc3J7FwJfitsom>Syy5 zQ^)vNvy^8RR_95_Ii07l!t@7a9!u?@Q*&5REs_x+soQ$lh;Uf|3FwO1*=5VtNnWIKiJBrZQeJ~~@k2g(uymd3(zIkC*$fB0G zD~3l1a%KiEY`L2S$t)E4eI#_!8CUCPQwPi=@PN38uy=V?qbwPdrSKpDD5eR8E&Oqd zP?l4!rJ}iQD2Mbbj&l-48dXCpYfjIl6H=93PK4G1+cEr6DodRNYbv){?x{ zKYVf`gmI{Os=JxFdt)OtrW#`)B$}Dza`)7Ye)Ci!BW#8Gi>_5jUHtBA$NKAh6tjuo z%C^32^#_~lXM@3BRa~)@b@g6_+FnBTYq%d}{q@zr&OfFA@Cv-aPf_{o2k2+qAD46j zmxu7R@Ar&x-c)M~Y(Qu`+TOgrV`x|?m|53p#Rk`00XrCkg(*3A0NQr0wWjB?4rSKJ z1u`|zU{wyFssczU=gjIJ`(e(RpjWT82trDYsIOH&Co3d0cK79P(!}p(l_)xpO zc7^+zQ%)(V)F2*s35{>WPC;P0jsehhRG~q~Y&z%4M54e$W{V;Unicj4X2dE`ozNPm zlX<&}DR5#_TlbbyrxZ7YOAtJ|=yC<5jL^E%e03co;=BOfVo4Lv1|KQ%L=Rk8r4yyP}vk$2bsY?ZG z?ip6B;oeZ8MFeJi4>BChTkHDF8EYXet+8CHS&T0=|5E@#uu@}LM3l$&el|ykk?5R3 zx66=3?0-0z#6t{_am* ztORXDwfeSthBr031kPrS0p%fMxTDT)ej3J&C&3+NArA+!MD78grWI z4ob-^f;*cfSEZses>@-i%`_83&aIL>Ckq0Y(YhR`M3ZZJbasBRJAd$KI6XSLdGqG| zJ88Q;Iyn-o6o=%h%w|R=ySO;ZmQwTjj@Ba(0AH5uVBSbfiE>nVEir_`&eUK#4mX)5 zL9G~2nk9ub^zZX-g%e*8DLfnWUj60ep~0(xP+zoMZHS+UNU(0PYa5Wy`1}(n#1|HT z&$Yblh!-6PLDi`;_2 zftisRpt#8vJwNI44vQorxvH5-;rSLuc%RBdkP$jEK%5{T`0z%;DX#`MqF(II&Yqk- zeDLVK2fN2lbWui2Ls-itD(Jab6arkhrIPw{J4T{G%f>;pfR25m?YmE~Q04=nY-`w} ztDo9cXtbyH|CQxrLHrUWTkTO?`mU3*X4K(Log4iVpr;Y|;Wfg-%zSZ#&0)}^q}s9=prCQmnOAYgavOQNWByLC4vSSdmte+(@sHj zL5qIhO%Iz zf_jZ+R|@svk8Yqy5Cl{6m6uRp-PyXK&w$|8$y||a%zz>){!*#mxXFHzKX~=tAtsb(VMRhhL9(>B zQ!PvplRyG1lq{?t)>fY8eIwNGJkQ^xzy^ zp`ZDNJ>eFq7O-UnU=QlmEbc+<^cIoANJw=m#odQAY_}V)?o;(zQ_d-80JYY-pCX4= zsu+@$v;EVDPtPAbc=G;7zT0bZD;i)UnPDzm?54y-54~eNwqeA!S<4|=LxD}aS^JnR zTIwz%^bMvBmuM+7&Q6m3+OCoc86em}?V%lnux-=vKl8?p2Lb?hE&g1Yri5(-sU~o7 z!FPbXl&1A>kx3&rv&3iu0tR#Rkm38X-&L2a);begEG5Z3u`@LQutG2k|K)}_5;!Cq z5-i*vtoeaL)=-MAfQSJK-L}<9UgVi)NT80 z_$lhsMy_`#-p6e_A@{iJ0d%PdDb;<7BTg(4A!5WeuuzB8^IKsaDRU1kqo;T5a>+7d z<~UNzAe*o0k~F(C(amrDF70KZSzvcAu99qFlhogRHBA+9yqG8pUR+-zsM)-?ni`P> z81iV?j!-*_SM9Tf0NjI71N2ytlF%S^oaId)-G@HrRizU~z!cv8uvAn8t3IX7JSKNH zBoH;!1%bqk2*c0J^yo{MAWyaXf}0?kP>C=VCB~!{BQY?*#!jiFv`CX(~ll(PEKy!zqh${x;Z_9rNJnu7F3Dk>FJH#?)>6nXUR^EPXJ71@>Lk}##?jqf zo0ht}33iRsawh_0>?)zM^5p>?R+yYgNBKerJ zrJ+`Nsc_MKa1JzcpU%%8K7RW2{g2K*cvR0XvNOAqB|>ze6n8S&(12;DC;rK0DA{q(E@Vx$l|S`yRLk}eXI79JCxKx2*0JXSH0&i(_BIuH%G-s6d_^(m2x0%m~rom;iJePeR*d*)ggJ$SPp+)L(q1+2hCmKXw5WBhj#_5v<^LGGBL z`C2eoWSr%UE9KJco8jMqT)i-QW|^QD@AYbJX{#zN7^zz`=4yt_Nht}Sy52XWLNpzB z=UZFk3WmVg*VvI70XP~dX%>CDurV(Otv8$WA^=K#Bpfbr>T(5~NR9laYDOehDJABd zBD(`;sVB^F&c;maqd7<~@zzcUK@UIX0#UPTs3n>?fn-P~(xq&M>MdzRo zQTPrCl2?bjY7xwA*rai)Q>?uyTk#3XFf&yVWNIdq2#eI1_99_4rBuCeFd&&EdAX=5 zn;Cpx>aJXz?e-5I+h#nycjx5xt?kXz&B@VDUcI_|8S0SoI2g%kzmFBnQWD@^oAAVL z!Uf@T@|GCF(UqDVf7#yineqvJCN4DE>|t{rv3T+(8Q~W?_RuCR~t(Qjk$dI zRGO8a@NPfBX8t4sfPU;6|E!3jFJC@E+db?2>yH0~M$%ztUaQzRIIupW>AFKJ&2Br@ zynWAP(NK7;#Q(@;6?Om*S%Mw3THA+Q-a|UDtN9nyH>2dnP@cIT^SVn-+S4o<4TIpN zOmd)lvNTxMG?nwGj~_mH{Nab^4{PZ`yFjJVANz3xuv3Kd43D>9jh!x^^XF_v7>AUftzNEmp5Ry90&bW9Xt+v{DD` zZMEoDM3K!8H>%m%xy`FfTQs{%&3Xk}D{beg5OT=u85=F@fE)>+M0aOOB5SRAuyM?J zNbYVq&lUp%Yw=8jS9IQ=b&mqEd55HGw8eKvWHl&L$wXsLHe@AKXfPvNPGIYiMM0AX z%61|0aGBJGzq=A46e+{BuRD>Dc`fdqa^xnE;3=h$3Cv8W(b{YL3W#P77n7EjYhxprm>*Nsj6|zBzI@K{rN@NT|9pOgVUS0HaAXhymi;cl=C36l!<0C<{?kh zL^D?;?&#T-NwoB2f_DyRjP7OP%w|7^mZK|n=4JWPknhuDr7^)X${M@s%E4z8KI8M} zUOq)=@*?-S)Gq7w?OB(vkjG2ZWW7v$f;&97MxR4@X#wDp`1G7}z9`p}mzoBzUOOHR z?-#G%mDlcTn3+{A`Vv3*5kj*m_f>QzG$StV>usY7F^tptOgARD!$D3E+_Frmj&*u8_omm_YdZbDNNnHo_AZE@gCZDROTV1AI$fo!1vP~R^WubyuW z!IJY}Wr^-)mQqeB<~m(VcpPbl!Yi3FhD$dbF&OS*ZA#@fL>)+DLUPMP8gr49QuSU> z!CTZ*P%<}KK-5q*5Fp$<8InUvfV{$#QYxy1SUnl&O5v*F&9tPJd@n(jbI4{y6rFj9 zgfzuDBu)@y;%pCB20-#;^r}$n!>m5N(9`|VkeIM@7i$qL+tHY*2->6Y6Kno3u_OwJ zlyV^DkOX(HiB>gPHp&QOrpcW|nWkiEOa=l|ot{2=`sCut@ZN*>-#vcq_O1K(hm)i5 zHJJ9bU=Jq3(~v}}02XdTas#STb9q;9?9~9(T4V)bD@)@ca9?u{=dnM3>c-M5Q$?4j z&&TY-FONo_RX#C-{}iGB3*K;k=`~(?aj{{2=JOkmhaawAMPI?PykY)nsP4~Dd8wIj zX&hfIpIYC&Xtl1O_^Xvz*Y%p2*B8A;@#jo2UyJ8`lfQarvg1&w!{NS|N=-#4P%V12 zAyuz5o9U^uo+dcl1{f^7GTnttAQ&>9EE}zc*Bx!JY!WBedAT@0d-B19NAG^1i=8eC zi*LkiL!y<79VJU97|n{iNUsVWtCAdGLa9zjMo%8pg_feWRwjmrK;sSspk%Ya16Zk7 z5BfrF<3$6h4KA96BLuD4St9lcpcL$qo+m*G0ZicyImMkV+++zQD0i^QkYYMHNsJsm zfsnhP5~{KQ1yN;h#F!T3NA#LtmIS%v=4Zffe)!?`^xfqA#z!BX!(~7+S4~XrlGUyu zCtyZ6t9v0xGqc1z6fd>ZF^{!WB74~FDQl@=XMp%l_4p*Z94gKs zD+z)XkgR)?%v(5D(m>n7Ik!faT@m<6-3x<@EPQ1m9m=r1hL>RU^UKRF9M_*eZVT@8HbI^7k4y*Lh12Q6@Xrz+IEYTe#$8j9TO|4F&qc-uRr;iRkT!WC! z2`DN`^JG1~ZV_Niq|qF%L?03c4kz2;^!P&Fh5IV^@DmY%Xadn>qRnnM4mfBv!&&!;o`z4S5{gvI(_jI04YB z8&Rg3^H2*OeD?>?0lcUe5NMVxB^$hy@N(c_LmKF=y+3*9!;2?RpS=4)K0Uej=Ih%VC!3s*vnRMv zONoAJF)AX&oRlOpO7My_uL@m;Y%O3dTB>!Cwn+$VM!9+X6L2j-)wKMAHQd+1Ed10l z^~aUx{i?+~l0*;zM>$$chJ^c}n_lhjW)sH!V(8Hl#AT76cPvt?$bpc-h` z1q)EpSO^UQMj*H1lFTews&Yw#WipkiNJyZ(=8%=Aa{lPigLgkXfAFZBo#UboqPY@N zgqEn#HVqW_mZ&Z76iskJQ2`0(1(p=IY8cvt8Mv z_cf3!w;=cjufJCIb7Ge>7-XW$;E=OcM@~ce|Fies!Lwz@c_8>@<~jFP)z3fQ{rWW; zXrO_Hw**Lt24oZT6iLyDMx;2RG~`km%}i(%yQ`hp-I$2ojhR`+%xqAUW~8M|tTd8H zQ6vEx(1RdB0D@}}9_{=2_kR9YRrj8gnfu4Nx2m3P_Zr;|^aZV3b{~Amvo)+f92DIYMlkJdxq^U$VBq3B6~%OOBa*sK0ThY`A_uP8+=3ZoM&_lq zntRW!FY+(wvc^Guov@y%-m|FC*+JcV#V+it9+duZCnZ3*bR)YPb*i+$EHS;C2iDIA zN71A2>23h1Pa`aoV8NJPn1omCRZngT&yFygsZZu7bp1cCLMa#UFTxc+y4qv8;n}bE z=6qgvmgmf^GAeGV84*({(9uO}ig%`P;xh9wb13EuYC#QXq3g=XpZjaQa|@ppAnbj| z0*k}R$lW8mntApRq3%Kyg20KH*_nI3nlQWdBCzFrj*h4UFqjog0sgPCqy!-OcB+wT74 za}P}(JI5 zaTSm|J*-9>0z^av4rn$OC(tkiZ*rRKrLBVtn|syrXyxePr9-RLuri^nZs<}LhysLw zQem*$%Xp?PP}IW;g%bpKSED{$a^q>%MM(M_rbU}|=15&NC$0(t++b#2=L^rZQTAo_ zS#HU>o?f55plsjkI{-6d?MB^rm5cRadxG{%dTOz+Y2n4KZ%;hlZ*U)rKkPHl=It8O zA1F2`F`H$M(dItR3?wY5=In0CXO%%CcV%m5Y!d2YvW06avlui8P7rgqY{EiC)4GW7 zfW7z)Om3cBiAX|7ZAv)>W&x3-VqxOx-gtL!clW~9bbrq#Et0W0D+MAcrWpkzWd~HgfH{uvl(=R)Fh_u-)lb7M1jJ0@HGF9hObd4kfi7 zp7SD!Pe!ih=5RMN2&qGeNU01JCsUMEKF(&OI;!g_G&30^R27(+kWvmTj^Z8ZY;X|V zP>RBeCo^+|5bC<@&N*wvwW$e(GNdvoG2FEOt-=b9DqYF7^1Y6|(}n(fj}=}WpEc(t1^is=-P^N^r7dL~!M5Lx7?BxiBs168AvKC;^8ib1zsOBV{O<4LQ zt43j;=OT9+nFSm!k^=_I9wI3v60p^7 z42Tya79`B(2o#*C(T2!sjz%sH%gLO^J3Gzh#f{reF4b{YQ)D71awP(@SV|HC328D4 zOd^^~6+(8K6X~2f-WA})oHd~m%>ZgZmA_8HeLM}SnMpJ!azqMdrh5~eOgDGNcx-v; z)QROgZma6532sqar*_&|fRjmq zQdr>T>Jj9QDC~gkO`A#E?Co7XQ!gK08?3C1R+mFv=RgLOTw!BjA~Q9!UjM(_gbH`G zpe8deruRPk)#H7Ja9zj7>bATtTly&&&NrXW&%k1ML0Po7*eZRl{ibKTUEcwChJE-I z+hemCdy_kSmPX9=K(w2D@hLvRC;RmqoO}`Rn_K_aIq0J2`bFQK`@*m`OzHNW#RW-&C!n28gOs;HApfZ!Ph3k))HCNppdZkdIH1PMWe)s&sI zm!g0Ye6{dz*3w;>MbchH)5MatO1Ct2#>E+(Q4+k`k}pItfDn zO{PMjNX4qQ?g+t!#57qphp$%7)VM^e($z*E|`@W!^E%*kVGnVwQ32NwC%yx-uB+Xqo8 zDTHWdxiuxPV#SQMZ36{JFhkN5hyxLGAUM2rHzo#|nF~nGOQn`l|GR@uoEQ|8N)XS? zSzuXhV(me*y*~-V&85}V)#Hca@`z&$B1&LF*5t;PH0NA&l-)s&t`dBK2>LagX1Er5 zWTqSAgg%(KFcmsfV{tc~{o)!6;3+Ku&(V7EA)_~#4XJ-Ar};H$bV zBJS5h*o%PHRfFKF0r5=w@g~FT7LU9qe&E;p#&v&H_Sx$njb_l`?B_H$;(Ke$`HF7u zzfGOeg&~(?SOM~xdWJ;@c9|O^l$11gkP~wtCNqbrnh{e7OpYKGk!x1XD#AjH>=h9c zak6%QvcI{xcX@lVvq#w|TO?-Y0D@U+%f`b!=UYmhoYs|@T1x~7h>6X>LL8V7n{mVN zibG{o1FJ;CHiu+MwSd;<>Mq{lf+dX6F>*@x6itj-UlS3Eb~id3py!v9&+{H;5&7m`G8=2;rLDowO_V-mDGfI7>uA`(1*4?rIRO$^oRG2^lz&sl~ zFcGuETs`M3%miqkSTf(YyHRNUNGuz8r_Kau8NX&u1PPMe%#;BzXE!D`R)&|dM=We^ zC1gWPT*yS!qoZ>N`sxgrYnG%JRJ-<)Z+HiOeic}a00Bv5{jg~_mzG-Aig_$pSKE!Tang*X>y_{wK`>OqY$xxos5Xt37>F*bXoygzeyiPU-PeI`kt9Ilo$CwN#IN)-{%nwPAm;xJn3gl-8e zB*dhY$pgUd9D*=$o0EDTN@OQ1aaXlc0}ND64k%`<{jQUf$i4KYg1 zs3iK38<*4J{V)FCbKvZOwh3HGF>)-5>LGd%V!u`I8$!En7lZ*B7{UtIO? z3v)>>?V0BQJe~I3_tjMo>_%SQwa@#y$GOSBcm{)h@d(#`bSs-*`T8bq$94a_s>^PC zakKRgy?sbbs+YRN zOvUXZgenlo%rqr1Viir@)kvT@i9}{;Q(ITU6vor>s2UiYDVQ1h;zF~#@@KGYJRjRr zUazjZjFj~P=s{Lw%e?W+DN*SveRJv8g#h%|aDpjIPd+JAPQ7FOC_~TV@$LU9IlE zsH;6^?%n8uo13aRab^c|6mlX6nJP9}dO z_YN*xu2+_-wUsce>)|pd6LXm%`QC419rjZG>0$!jTlNI>ut)dLd(ySNee;3xxtSr>m*RVGqL z**Q(SVlf7#4x%OzAwU9|d2Um|#}ka*q&! zvw?utbFl->%nD%~a3+sL33aT@tkAwWBS5^h5j>_GCV8^Cx%K#&w7tdq)6i%jRX2n{og^A}9=^4mPDy+>|=-i+g%jr_$l2bWjJ|Q>Si7CGQa+c$d5B z=qU9LVnPQjmMy#^E6qY7J!>B55A3BZZs1T=93ohNtd?U{sTl|grq5DjiQ zFI6Ll=A1%^CAZ+J)ETjDE;p$;$5c9TV>yQ#8DxI2L*MDql|+=MyAXyyfP z=1M@MrUpYOS}rj2BCG?qZkTo6U8x&AC)afe@kVtWVhGcALeOAhur{|bL^CViI75io zOj!sZbB|RFQAz}|tS)73pqU^j$h!j1i#v$VW|YIYB$vY7J*$G**eQw$Kx_aLF@c@R z@&k}&l}a>gBmz`81{Sw$rEH;Fmq4rL#uWuCGDl2Mb+=f#nt_5cg}|ON+PwMDqvoiO z9;MN6WmIvS*)3-cM?8?a#t0!+CY^>x_WT7w&ZAzJdAXP0%RYH|hW+&oOb%6-dqfF?8 zP)iV$x@zjBngrm?APQZ<0Va0jX-mw38ARHqwzafB@k`rrROi*znrm&6n}LXl;mYVe z$NAQU#c6ouusJ8p{grDKKc8^oJp1h#p5%pXGWP8WZ{bN>ZqIpVJR=9- zIlua+)BHM{>J$IuNq&bGcH!At@Jzbt>F(w;DBza1n;h>tmw08CW9gEaHQym7JxWb; zgsg{bt}uuSF5)vE-}xN~+gRe0cDAX|GKO)g3gfC0u5g1ehpV+llV$_i3M;mRqf$waYx z&~9&EI(;$i?&SS(O$ch%CJwRFFCh>YI!!UBiTW~3<{ga{v-HM-g%|smOHHv}2(>s) z9lln&)r7eMmWb6%_x7nx6;YR4+{q;oaq*h0sGF-<36l$xGdp_`+Hotc16V?duY0NM z)jhgmRDqp*p;GC5BzTuI+$Yg_G3(r{lrL~}dMi%OPBYKYyCLGBnVr$)Nte=`P88}0 z>Aa90_=7owVhFKq8_k&m)uXyet&8WJvSknj3eH~g`3jM#qhc@tFe{o%aEEHqc0}j* z5Q%VBC3RI75tx%e9RzNTm>EuBVR%;cKq8g5x#y>#r-58&;@)7^T|47$A@=YbwyRds z>wKX=t_;@fM5<=YV#wxdrD|;87%+8nGiD|LLaGJ=3(U;S3VWNFx~Q6!V4^XY zrQ?majW%f#gcvb~YB(C^R#mO40y(RC0C`cEB8YHRRXu(WVCE>J6XEhJ@;iEKnc?uh zwl#IKW!(WZ8%Q8VVDyulnB0vaCHaK_B8ECa1kpW_d(N%H;2r{36&qaJ99=>bw8=bZ zsB=<=#7J#A;3%pcxt-ad$lLpyUw9-xcJ9#2?i`&sR#$^|e@Z!fksc#AQ)W>o2c%Tw zbDGu3qHb;HF0H-*?G7eZvT9{Huuqz?=j5ra&r;ybu8}c-7eXuAI)a_6v1qpxVZ%qVOKRcM8v_ZW(vXv z2&URJxsAi>r7wTk@nc619a>)+F2xu{q|50mH`V`J_Gh<(>XMtAnz>P*j_&RvlClnB z-A>c)?(Sdw#it&7=u9(hYY9Q(_+UC341&bzbh_W5u$3Ncuz0n+ig zXSuRH%+Wt9>iLc3T_QKLLPhIHLS~+G`9dz&M;xdt*9EuSwx;S`u?{1!d2+ZzK^CiE zZpo4+4J@e0h+0jNyvZ3-Q>@aoQ3r8^2%zlNPR9gPaloE!nwo>@wmmwzy!DD#zUpv2 zI-^>gBc_m5IfiaMGViL0^nSFNm3cF}dowMChcn^u(Zh#sKX&2r#S7=p+BjRQqKHC8 z?I%cRrekIZOP)57Wct|j@$={F!yAY0JhgQ6NIMKtORgmWIT;C&P%1?hvzH~wy3jH8 z>JC;ifDNYN#t1G(fR(zxL?opegb0Hur<^sH)SXyWa2Q;hDU}t`-MvtotT+Q5Sk)C~ zzTW2DZEOo~dXWz5z<{oZ<&~3RVZ1E<@J4gzSz82de&Cz9?O#>x$#uf>!Faxz1MpO@ z@A>Nw_%$z{jZ@Gye?Cj6`|<{u7Ebllj(2qj6k~sme-!)HdW8t0USDMv{hTRv^j|2) z@!mS?fL{`rD-j5;Y8*t($SFuD92QF%4gm$0Kuo52+D;F~`zC$Y>7A;RT;G3MS7E9SIBZw#ENI@i*2u2B9^finNYSt4K00I{sBrj^3)VpQw?kvR8SNn1ZGZ%xk z=%o<5+QIqD2Ny55sr5Foc>od6wyiL^fr*4`VuOKY#!xO*)fmKP?q-pzAe`02+>n{2 z*klAPMNDZ<0x(zgtOU3g=5MLp<$WShc zxDU3>GS)E6-XS>3z}RWog> zDnh$}3A)K~1JL{W@7)Av`^w#f`{l#kM8wU&$d(i-*8HY-yz%?K|9fBcnpYh?aYRaW zIRgPfL|BSU3lmG=V&${2lssPo6SFYQ95N!Z!j=IuSifA9Q!q2lEzuJ_a)Zu9`Hp$=z7Q)rg%$ zO7cmRfTi*62)EN#B(O6J z7d@o_amNVUZ0+rC?mV)ehr_D&vUWQd!jiIi1gvxZJL}fn+?WHXLn2Bg!y?0gk|Gph zedy5I`aq7aZ=bugfBsU~Z=|FL5P^(A;skPrnd!hHwP;RXym)CltgWn^ylv^kF>9-+fR@aga>?L&qCKTYLP^UTKt;VU(w6Y3#~oD z!?>9Y==0a0f0FH4wZgAz*Nuza+Osbn@X5`wr*;0PH+OGzp6k3n3lnr3MIR{dSGZnW z(yeeWW&ml~^EfbE(P!SdnX{22O&ibV>e*GQz{2L))q>MNA{!_x+N>#$_x5%#Zcg|1 zb<$E&R#XfEvr)}}GbCp7L{7wP4t5qXb92|6im)h)aEz&KT@|3v@r82b!pURX2G!=` z_Ri^Z(@U4R)!N9XxnhD_p0-sLJp?rkbu@K#XAzX-zd6;MdQ=i-&hx@Co#E?nGUre< zMomf0w7{8@rU`XT?wtq^iJOUAo*We6i$ENN(zGRl1QwQT>h39P3=EKx6QF9$Qi=+= zDu_f%IbKHAZpQ+dD-pq!ism6eV0UGRn!EO;g=Y8FJy1B66bEiWA=i$O2T(Se!XOE4AJ(@NsCFcDxgbl*(3O*Kah5;1xqRK2!3(!tcbV&iXPKpt<6|9L%RIpA-uRlo z_LDz)-?x1u$XAw^q+3`@qPF+hxYQ%H#T@K;@g?Wm3l+ONYacW~kg&fyK5_fuANr9W z81Ena&;RfjnrSx6U^tr_F;ka24zNh9DlP@~AlxGw9n#-Z#T^Twy!n5%Qv-07QUm}n zGj}UR#6TcobtiSAQUS$PmAY!*=+v|nEZl0M$SxXU_?B<`wy*iRH^Q@-wUc)9;^oU{ z&p&qd!lmu~i|2QAzkzyHGg^`$+Nv2LuxAjEn$e?m&u{OYKCRQ1+;!SSW`mk) zkVt?x8L&#&9h$bcw)b`(d2HpxiPbx9uhvJCnozO3LfD+G)QV%uDGM`8@%pHvN;*Xn zD^oiCc{&-}2n zw&+wmxd7AC8iCJzUgmo7qjm&pX0&Z#moSZ*+I-4LMRFpGco|k z&B$Dsk~!4KNDx$~;uOW%tlgjNUf$Z@+MezmpfxtG)6Et z%W5TAl!FjCyPG$ug&V7rnh*_HDi1VmbZ>9}@y+ShcHZ8VCfBWU%0i?$J2N?|x>i?p z2Xkx6B!vl5_JTe((%p2?IqgzsONH5@aa5r2&IGnDw&8A?%^*USb51$uButhSZh?r+ zTn(Bbj1XcF0NR?do58b^gf^uRNud&|P;pThLMcxQWK$N->I7k7)e>X}ikMxOUdM() zq$e^rRd-_&>xWnuS^zt&TsHTL8UU%7b(~>9;O3Wph&PB@5-3=^d zH!qywGNv_axr`WTd@x;KAH3sh-~3np^7nk|qn~OIk{bmH0ElQ1YU&R=-`x8dAu8SXDlE=%?HusX=<0YBoswxlN)9dC&XEl~UnW^XEB|88jVxf}i04|I{5Rn%l zUm`OnwNAK~-ObiF*1q=#zxSK&`?^ZZO$ns!)UsZ>uzlvzI%;Y(&JOrmF6YbP1{ijKB2o z_{`br=%KZ{@2uCCEpjVaiA}hLb5&-vt2=>>3(8WSwR)$=D_w{Nq;5qDnTX7d;3b2Z z!DJ>yX95l>Hv25?%;$7P0swOlbOo4?dFFTbAbs)CcZ2&%D`IxYSvvFLe0aWDnJ-$6 z&&PJNQF2RUK%am9!gDe){F)cH_Q+2$r0{e*;OYI2uDyT9+)^uV^zSUZw}1-6LFf|c zW=KgNPwt8TJq-iBj+8pog9$egM4#vplNoxs&qW<9I z=!8LxjLC}j2C=iN+Bi+67>4eHP@`bKrtYwuYKp-*x`if(rqR8F-7^;tE?u&nu{Uir z7e#b1V4mwLs+pRqD+{-loIS+KGbmd@yV2oB-YLs1-u28Fof(JZ1TvqCT~i4fsD&WH zGK!cuK^^cIB~4p6Mdlz?i6*ou#~9+U%Bma$bx7Gc1S6Fgvlzfe^k6ioUj5qF-hS#NgFI(M?&`CeSy6fw znXe<|$UXa?nLyH?kRZhgAv2A2ECRE_RMnA~+tj}0YuFZ8M|fypc}mYifg@EX8%XAB^}IaIm1recIx$Sdh_ziGOG)Sm^~}V znMhMEIx}4+2f@vm7=pP!(ZR3Y`D0978WI<;(z2Sts)3xm^VqxY`{qCVgFl(<=ah1j zh)JB7Ib5>UStU|8fzT~b1soxW>!n&CV>MHn-A-1%xzMntORa_dAPKE+h}z7sE?l{-X=;O%o$`EoQ>ewRYX`=vnoMYOtZNqSO^gg)jSZ1A-K7dTT;MGm5C!! zaH$nla*WgT!o}^=7t+qIkEb?iYbG-dES6d)))HujA`p>e*Ib!P7_F?Vt!-R>_zb1O zDQ9#Nlts>a<`xwfXJ#*S3Q7cY8a`Zl%m8PA&Ain?EopCmy1Ogrz-b}~Nx?x~-Q5RO zZ7|hV%@8D1GFYltj;yS%jqZ8X%Wpq<*YV>=)>f95M=MUWy}h@yzyHWXkDoht_K}Al zx$yWI8oRcpmOwGnBGtqC=)&eqi(@7PW zs7o>-CV9lDldg`t_s=D61yeAR~ zOeAntb&izPiBQ*(g$YE=uqzzh0yy(boOkxjyw8bWXoZ%P+YARg!HKD-jTL_x1a(Up zg)eDb1c4YqHRt3GqrmmbFb8Nv%R=BN)HZFwF(^aFqOhkp0H zfAAas@wZPu{&+nSHZgO!Pupp%E43ViOxfI^3?|LFj#AE9a&^qD6#4K{PmM{{3h-ax z90{d3nuic7G9ORlKvsuK(}PB;z|PZYTS?SFajiN$94t)^w$GfOT)MSi#_R)y$Lg_bG>y&+!k z{1PTATCp&I$aEICBnB~&q0j4Z_(Flil7HL{-r^R}3=#7#YQ4Cup#NxbL=;!5-ys)9 z#e7ygr|sqz$XDc2^ijOML(`6w)JUsrR}z!ys1Fwv};gHEnJm zY;TXxUT(IxaWLi9s&dsik-O#;tKeS1M$hEQ6_uclygWE^+lgaGj2OYT_-~facMbJK^VfZRh=}6i1xO}>b|+T`M_r% z{G;Fd{XhPlKcuNyG6YIV8G$LAgGto0P_%5;rcQvnf9hskS^>NBA4tK42E#eIdNgj zlwzwz&Pf*&H5Y6ymC`nQb^4FaxeaRb$G`M3S>hU}lzx zs*XWegw(88I_@-Z%J}K$tItN(%nfkrk&zNKaBI^PMQaiufSt5lS&4iZENjU;1v#;i z1{4A$y9ZbBG*tJWIY$?c4ToW4X|&35sfwA({gWF6y1X))Htj23dB@2UKl1Kx`<8$8 zFaO7c=ANUAy!L+;jqa~98_+w%q_9k6@(7IY$@Dv$Ikh4o9E9VXEbeU z+UUgOv4{k;YL+Qbh^~#=*mn1t-G|St-Fe68_M=n<9*GJkN7l@Njj7_0+swj3!8;N^ z6T`YKrmIy_cBuJN5{ElO(6O~ThF2*nO~rRaSrxbo>CCsd8S}^Ifq^R|VQ28({G<8% z3x2_D9iV4>u3vXKc|!d0+Rgkc(inT;x48rG4EBxZnXUa5iTz*IW+1>#V@yx_fnH@} zJoDhf0?=O?UG+f9ibe!-^HQT{aUt}DQ8i=47j&+uI|I(lAT|d;BEhq5KYGpwlCn9> zlUq(?5aJ>R3?g$2ghBM_!)o4b4G zFKs`129v2YnVJ;D$rYK6oCSc#5Zx)OvA_an&a^ZNN0!%bJ0Z(;tOqLbU~4y(`T~U_ z-)$x(*xS*Y%n4xWy`GLvP|C;j;1Pjf#2KQ{$#lHExpU@XyR|a_yJcbo7B~?}fv=Mj z)q_+K)i|`V_H|$X*6;Yv`|f%9%Qg-jjx`NpP{Tx>gdE;_Yk^Ch;%Y4j%V7Q3i93$I z_AU499&G*j``#Z>u@fjd7}R$5loN~sNZUkaLZTp0pU~W+V+3I*G9vM`%=Ws6%oiVu!($!6H&poLM|@$kTl8%z1!Xv%nnd zq2&ZKkU?1CW>(TLI!T!MsGM!mUbNfM2L!rw119gE%6KvbaCv+4;fEh_m_$yE2|`s@ zaL?KjiIw04(34KCoJcpFWjA=|Mn8J;GujuH7~FJ0xawTbo;_0R3W?2i_qqnN9x23qp<@>44L_}bEmYW1Z@kKMMh zzERif92q`h3Fb_Z*$y8XEe&q_`~TgZQD=}Y25HM$sj}m7>%0|Neq^!rMN=Lht_N?0y3lQhKuJ;FZnbMmPl50d3`Xd z7=vj}gF3bulW7}5wBS_7<-y67JC5(3JHLPa5=|PKCQ>EyD#lD&*f-jmuuDoZMn0JA z?T>dJd358YcMeY+(qSz%C+3Wl%n?w;VY7F;6+s~-<)fFF>nag;0s}_eK~BiKF39t~15@kj1T^Y){Z=;oqCI zuWTFaE27Xk7;975D}grD4z`x^qAd zJ_o}9x03vdQl^z0;$1ahi6NWm!Bod?P7;g2cg&_tXxq%N2m!H^C09s+(HV|LlffBm zt`cM6xw?86yEi4XkwkBsN{Od!yScZ0>GJsOMcW<6)+pyd1~Rg8NKUdaR4u_W$!5EE!9Zgn65uuP&n7(~#XxW51whx2Ur4$OF8FC0>Hq%0hVX#e8 zyS=yh`04%K%eFtQ+y)X`p{%K@;-pp10JAfPQH=qw9$Wgh@4oNb?)#Qgr;e|TXgH{d zn5sB7SQVz=)-{`|S%_kRHECE`7Ln<}IH8r*rIjNah!QxEQc`7MhQI+bCUPj$a+?YU z2&zCv@{?2gEsnA0Rb^x$Lv;g|oz+@hhl1^WwvyE)9gdsM(?)%_ioQ)m51S7pJ6)t{MOsJZGr&x}sD91cELx#+-~< zR#&%T*m6m%=l1r#*zA4s()m%4^{RTs?I-U(eC+sexX!#?f^e+Vz{GBW!kb1&L4#R<4F*!bMFXBcaIt}p*NZqMh4tlv}y^l7v&_nm&V+5KORc1t1v zz&vc}J!rT134j@UqBHraH@iB7+q}p&&$QF1Uky85jS`+^K-kR5NPxhUL8R`Ul|W`7 z1cHzh3Fqt}5hqTnWX{a7s&dZ3CC0kRspGI_N7g7TAeyEnCZ6VlGn?CwpPpXY!`!=HZ27< zN>T->C@kSSfABkgI_r^FoGtd23j1MzY- z7!qr65}A%Itgk1EH7GD*q4GQTd30Xn@{o-URAj>@BiWNUtJvx>!1vE$U>;VXizxxlbdCe={@eOYoEmfs{#axRKop;Dr911g!&if_EsW8~P z^``uG+S=Yh6Jj`b;leNe!ax4wKYBligT(2yaJh(uQ%b>^;38bdSjGwgJmWd`AaAiI zY3@uC;9c=+0=(4vP;z4+O_Mf>!ER=j$()7VHN;2&J3O0blfpxBqY}6x7U5P~5A5JZ zeIMSCHcXX-frU*|G$}UI&wOcr`HNq8+4}m|zWf!hSUTb7%g8f`#ISc zI+8lY07h2Q5O^qq;b?T?olIJ3F7(2L~%J zxozphF<<5!q3jSS5NdW}Gc)VTL8zzV1`-P?$c*4tq<)6@$OntLA(??8u{6M%Gvtw!A z4_?SJpf7++d@kEFA6g5;;He&Lfz5O6Vat980=ShBebX;!r?%v$vC)L;;|0fEL%rOeZI z^N~l}?aO&<7Y9wu3RQv+V#s+y1|teFN)Q)rRS~3>%!9ae=x|(J9o@cxrC|~piveMp zrT`CzH8&PqIM!6GS2(z@6Xd~N9AwN!L~cE9&hF&k;`G%;d1rEcZ6}47%2~o|7iNV?2R0)V7>}>D+(|_{M_s7%w-u0kKq#6&C2mtHPiyNdD@)BJ{n`8f{8xVE-+uc3Pm>2t*~|umDm8f! z>jLIV6m#`L3BEp`cV>$(n*KL3_is2K7Y=o!FI?B?zX`;0T_@zr(29Olnd;*1mdrtJ z{@@oL{D1$C|I^P+fA%eJe`Bm<(oEYX1qno~rtnfW!i(|Um3O0Aox!dTiqk+~ViFc+ zQbiSoO+NkUkN@(&|M$Q3p5N4DfvZAgDG%K&v#_c;S&URyk%&SFMRTTj7w#^?xlJrg zz0ACI&mN8$aST>`fTTj4l4_fav==iooVxTGLUti8el>{9AuLYjqy;cw5}2`wjG_-j zgJcc`vYxtl2qE}^*-p00m$x3+{_x9I4&C?q*S};qT4Nf3f?6edcw_V(-~P>O%NzgX z7yq|Ue&R1ggLzW(q{a|oNjW*&fC5^5{Qgge)zPcJ{hOyw4P_&9BUf<6>SkPWm4)2} zVCF~9pV>`z=d14hnR{RLV?Xf|zwyhz^5^gWv+WC)2lZ(8!o!p8ns_)`-B?{eksO&R zi7Rp9V1Wp__R_o7?>IiWc;V9Hk7+x>xS{OAre;ngMBKP~3(6D{M8Y&rCXXCEbY^to z_|hH6SSni1FovtT@(R3QqpXJace0)|2WayDoWT$mfdtfTjo{}qV?Fi@1o z`ocD4)u3)8oAFwKZV*zR_*LHNKPeVJ&+@_O>RCqDytuWq?HM2VMU?hN?UrG!PyY&D zuoR#d$I}zFS%m%>bk*W=^JEUQ_#O8f{)+mo7ai@jdvmr*&WN)!qU6k>n2Wyn#e?MA`+H|EPcB|e zTYHi;x?65tb6`<(V@O~@0H`Yw1xFQZ5H@Z@Y#!BYRBhlJh(Ttp=9S= zkr3QX_jl_lN29;Ea4s@0OLb?pzLP9D1qv+W-ohO&j*hj*{9 z(Ew+6Zgj}J8p4~89((iJ+9*U`TKROW586&xPzgd{1G%$z9aB;O`a}*6gGxIc)lw^# z4N7Dn3LF6B*0`3(A3FWN{=z@~z#skT$y28`)>j9E5sOG*qOQs($f-!VSWn?Vj}-&3 zg{&3TlyXkl&GvW4&7`?-`QoSV|J1oh9}`ppA|Xp=Y#^Abd3I7NL;||WEW2(<;Hl2( zC){DKH6xx9YWL-UjOJI?7t}I$f`fsK5G7CZCqDGa|L4~K>(#G)%^i2#K3rO=t2%_r z%+Sd_7MU6?qECfN}4UU|$yNwSH{`^lr`1#L%ZfUq=EoIKR}`--YX!7rmQIoQ5kHGQfaTtC157a z+0@)@77ZgXz}BT25D3hXoTM;Y2ri&1D9Dg4u#-(zoCB(!1hd zX}~PjF9l#)txH95$fxUxRio%~E407AEZeOd3~MeBdoo(S4|2En&y=(%5eO@19S z1Dyqk`K3Ce-~Y<5dh6fJg{f$*8KD5D%%pwBo;#Suip(VdFZ&`_B1)$4J=GCO1qafFYZrlXB?fF$lZjaxsr5satnh7 zP5_$|6B!x2#4<{LFoW2ToX8nTr%?k(VhK&tNQ5&Bs7ZNcdBs}P%i*X0^Pl?OAN?M! zgAe43r%(U!r#_Qo^~%@2^3AWm_xS2k&PmrtPLq^$bmH*DEvs=Qmc1Rjh-3kgq-55n z%X)7G~mtqO0akuC({;N&*0b%F_n9bEmviwLWmYXMN-KM~)q5 zuFQ`R4FED_3LqB|S0!>T9t1nM*G}T@Dx|K!3@9@xlvn^VGZq4yW+!s-AR%m>-}=CX z4{(rrPzeVDn<|y03zQ_hV)%C(yt|vZ2$`eP|0#)nC2(L}wc^~U1LPLDjuKO=@Wdi8 z2y-#r+^M*8H<+V0LWdTCqbHo6PkUj0!h>IR4bS=x;Dv0_oy&+}xzyi6tk~f}I9qt| za}PiGz(cVLA;fwxEIRI9EN^mm%cg**HWeGp%(}?bT$wfdNMLRb7>t>F%-6v4$*}O83rVO@gdiX{&ncOzbZ$>S z8)Ec=G5& zkMC~X_o~;uVrjH7h_y%Lyfg}ToI3J<{6GD@wUw1$`Q=|5R?B<4V>4qBbsG$8ohCC~ zs+T5P2Ot0K-+xnGt-kJ_33Cnx%_TpY;lk8rW#Sk@OS0GG4}bD=>47i4>eY9C{p(+U z*ReyxL(6~V$9~`kf9QKZ@W=1}H~->aKmO2TLF0J$!t`K!_tH5YtQ@)hj(VwzvGR(h z=9;`3RF=IueC+VjvfXyDckX<%w{3gVHpA6I2yIS82*k~Fg4{rab2AvkgD*X@`^aOf z$B(bydFN<-wH-=TNt0kuu0n>Jq0J4mcob6#1W~}08A=LQ14&5?2E2p^bwuEkOq&@@N;;XA&yFm7P!ynl-tTH z0FD4=7jx^>T}q}MF%z4+nu$|T4(h>CxreERX=*NS?mT|3-Pyr->P;)^mQsk(-LtBb z*MmAIRZ|dC#VMK&LR?>3J9V5#!%&ZO6x-}BV(!@>KuwWaA3%DMbTi7At1i|2Yk&BGPyX(iKl{SxzV^*;dil#)(a9{gZDtk?j*1fnRF#6s)JWhZL?Qi?b7CTx=M3{s4I2bN z`}NQMX&wlT*zc^D-g^7VyO);_6Pf#R3`3H@Fyic{4gnV;1bSK#dJD=4*5v?j z(THUV(_IG-=XiN>iF9H3m6c&;hRQF3f5!EIob&%wkqd z1!Z@Dn6u^}AW%RQW{2m-+=wM`AlFW!py2Ut=I$}Z7-M%#W>@Vm-}_J>`!$_R&IFVR z4JKD(BDm!ynL3C{4GJ(hm-q*lw@kGRJU8{S{K3FX0GmK$zt-g#a12scBveX&PbcURX}|JgtJ z=W!U>MHM+Iu@8fgvO0xCx;gp8d;Z{_@pR)YuS^zlZao#pzo;b;6D3m(Rf-&#canYV zvk!ma(+|J>t*`o?Z~jKNX&w08-}mmX`-ZQ3bNbTY$f41RnugJu{2=1%jZq-PkZnUsf5?#`OCna$E%iJ(Qu6y`u6 zGKU+HQ=NUo`PCao?pa-3Bd**PsDlja$WzblR6><#QP=j^D(2W2M%nF1U+$d0hl?)5=5@|6b>eMF}((j5?NJ%>Y3wd9^+6f477$RU4 zxYSXig7-rP@k;_p9+#rmqBT;s-H{rZ-->mRvLBrE`oT#6$cWwDO1Zp_?cW!YC{Ls0c-YJ_kl;>%U|1>&JqUY@tnNqdXCbt6p z8xz6Ioy`$?#*(WR$D@Nt+|5+D2E!S-WKG2i#4H>`(BvXQR48|(iU9Ep)y&KZU>03k zdL-$ufA-TCc6Q$N%6pF+tp*x^#M`yC`fvZ8pBoI9e(9HfX}WK@(SS(AO?Dy4je&g_ z;_jKtUwr?c-8+iwuRevyNMoovv70lC6OwDINvfJdWl&W0rLCRc`}0pecK-6)-+b@A zFFj>ZY{;*A>%IT&EB-GR9zXMMf9Ze!lRx>u{^l4drM-i5JD0=RrQ@ew8kW}~0b(M| zb;y?7P1ZI}tgYI?c>ltsgUyRRmhq%zS8)U;BKBmt$yP}gC*vw|I&=BLxy_}EM+Zj_ z504#QUahN25^+nO$=ncvAi23a8`Om(i#SZ(B7ukuomb{vL=ap`O_$Vw`OKlKCLl4n z>s--bAy#nHsXB9ruYLcP&dr+~??t=s$+WA`o99yt&+bZo%iHs>2cP@)L{IRk_Sr2N z4s_l1Yf<+CoyCrh0#Wcentg~KH$exn&AtqP%)BhB?l4m+^?eEl+yH?aIeVj-nI*Ei zsX7<}7V`lME5)huWSTGUk1uWRowsR7PDIeIPO^j9m5ov4Nw`R%J84QNx)_d9$hfktLPn#nzDhu(Pn_z9t9kho=6H)RmHMX4GqTn=)SoWc??r;<UDGp5UMoRw|i!1;C@iI;U=LE`r_A67lcKFc-lgw~}>grdG<3 zIWgF|;|dj{v$y-5eU?u!BZ1(0JI2-VH*=5N`8tuScE^xypPrPaYd{zv~zH}}$%k)_G0jw~!$ zGq-t#rM<9o|8KnSYwPbkanH%=I3p#`2AG)&6Ok}i`@8$xBn;xgSV@*laQ_2mKY!-j z8}7a5ZEt$jTV8(mB&Cq_rT4z%@BBCahadlIKlYwqf6s6I=KJ=xcZL>pynE);pNjSJ z#%*`3pE#D7onf$~X6^_=YooP|mkc)7r(1gm7cTmE>?v8B1Bkj6Apin1Oq;3>49cf3 zY@WS1Ja%aH)QRfwDz6Nrj!n_(bte<|657oqaC0MPbnaxA&erpNIzA#vKZs~y#&|!T zdtY{8p8M)(PYCWjS@h?bwCj(bXBq*x0>gN=+l$u!(`wI2 zfM%8%QeX<|l@P8lJUVQZ=5fy6ra>`}(DTNNnPdF6 zH**zGV5VfjO;Q?|*km%ku(fygd~;z-+RRBMxu`O`L!-Enn-xhu*T@EGT*GLva^z6G zu~r}2sMnVFRlSyMo}lVfhnkEinN3p+(I;uVvvuzDg@eo6oKiGISj`+_2yxKbWNEna z(wE=;&}SbIV%1C>2t_#BJ9fMoQ%5q^tn7eW;8=xFJdrw9(}RN$gafB0MG0zV%#GR7 z>cEn{?rm@U+yCv~t?oMVkw+f<d?mY(#1fiCesr%_{LYhc6_#Z z--kXJoi-mj^Xm`(``5hr-q-x4uUT7(iK>)SavD~#9VZGELm3_+ttS8slE7Tb^Qv}w z`~Zm6oQcWF&0yN6HJZCI1z1T9q^wy2lUkMRXcgaZ>b94zuB_)aIGH+=MaMAIWTkRb zDc9K*SS`9PB|0R;MZU*eV^yK-p+uzwY}TnT6EoOh#0&$3$*jvJ=pCvOqbj2QrGhN? z8+7l2c2M+OWU^R_g>-_yG{?xR8spV;KZbAT#SE~lrnK)UvQWH?Z$!OUUUNb zCpY798K{JaN;sedmYf(MVhSkhikk#+cVa0>JQ17cg57$dbag`ubrmHD5oyj~Qd93! zR2(Sg_slsf9JAh8D~=`rXC^jS&bes|eU6!kVCrz1-4Qu7Co+Q>cX?3morll^DFlfX z2O*}MmB|4rv?3-b!Jv^C1aq&XQb$&m7$;m10=-qiVoJ znym!}VK{A7X{ct89Za@9e*dQ)e&nt9-2J9IPKBIC$HV&JwZC=hZ~XXA{lt5J?Y;l* zSN`q(AZh(aY* z+&bl9%c?2&p%`LjEh=s1y{tcgtCW6G*lgB0Z{4iwcDpN#Lhl0$SGR>3a@|PXi|u*P z7Gaz#pW)0vdX}Ep6T&nvz#M=V+hTj7ar0$f2^LXCzhYcp=LHd&Iiv$W=Fn{Sy<%X& zz0a$12T>QzcQ;4YY$A-pH*qHl5*SF9g9rP+dIDLzWeUE=N13Azx#jv{3pLqaZN?h zC0|A6LH#b}g0XHC%Y6j{a1U1JE@wBi6#Vzh0mLiJKbk-qU=-}JNp;BU*x zL%;Kx&pe*@aqpdPH<5F+l#Bp&H8nDba5bnx5VZ_q_be2^q-q2vk^-cb zj6}?FE)o!XXTgJvn1a(X(@U0D?phkHYFY_QS;;L1u9=qOAhPTwMT~)1U5f(%kb_ID z%;E_!vy({`5kv7e%$>=I`^pL(6bo|7>cjz5;Cx3ZFWqg#)HC(_J-agx%h>EBK4$fO zsL%ZiAr#Zj+|UPe`a|@7ai>>=E(7?A&7Pjbx_!k&T9|PQ^nn|+7Y>SYtsCF&L@@Wr zEF{pZZAOs|Rb^0DiQ1^wwC4~)i~&H2wgF&gf|mfA!2^l+l0oi;PzVBLVI2ni@k|KT4sZ5E=G8*jA^RV0QQH(smnKYrnn zKmYjaUiXHOEs$u*Q%Jdrbu_VqMCM!(Wtgg}wM5MIBrMCy@FC0RKKr@*AAaohcbt6V ziI=Q#3QKzQQ2j$c`F-E>L*MzHU;WMB`t9F+_<=7~2xNZwv4`}+>6OFB4;?>Fd4wQR z#YDl#Xc(-nm+u;_+Fnjv(L?Je zZyz2zq67DVw1TYa!PUrsP!HIEqyPz%gn;DkM#5%Zy1y%o*pI(%SoVXw`0JR7UQnO; z-3kwxRZ7{W|6#>9TZsveG07WpT zqyv}GWE!Wuw?96=eQ@zo-Z>Dp$_#3-9EH+!%)%lJV@8$TvjY-%Kr$R0zWuOltW}3r zGE>V0QInvW1IL;{Nd@p$t(i`D$6H&Q2aj)}nGQroKu&2i3?WL0v0fUz^zfl$bv;a3Kn%(5 z?5H_Z6rfhs^%$<2g=T^(prWJ!CwFF6PuVSu23*IIHXTDGqwF&#ZrO2*E-8_7&*HIu zla}7zM^_EHAJj7(kBTGOIU$|*QMCLEf1K#5<*>u7-L0gU`aBo#CKLH)tKLE=ZDH12 z`J2UM`6`6)NjVwMWxIOOpGBMdrG(6lI{;PsxJN+}$|qcMw`ZPJ$6V_8T{?pmdg#9k zr5GFSd5>%7-n7uGt zHYsaeQ44h!lH8^u^1~o?ja*8m@C+$oIGL3YftfOek_81fCbDwDLR?8Xmk3!_fV+P3 zF1(dI8Pq*Ev1J9!oGlp`<0x9!546+Y_`+u<(6=2vafqpAX3wL6{O}L|!1N&h;xGQM zsj=PN0~c_Ra+~T_xh@%f@(=#>#L~vmm5uY~9tqWe2r<@aI^`fS0Gh>RIH>cUi*p?a z8ber8seJ^7KRj(uf94DKf9bK;-hTWICr=&@v0A5%_2s|%*MInje&UDT_n!B?=hxr+ ziU0Hora>L5-P4bcFI?O>d}8J3anu7I!iYf9sEUM8%i0}x9=q#~%a5PgyL18DdwG&F zQc27wMKsZzLS2c_bUa4)c&4ur-4z=BQf_%B!i_wK=-kz6B?TZnB7i@cSvkF)OhSdPcqr11}O|y0O!eo1AdU+Gt47hT#AOhjx(n<()_e<~kuJ3vG zJKp(@;rd9SJgQZAcQU=ax35A4o+A=-2P29A24oQyaU~aFZ<^p3V6ge{V~^ecS(;9( zz)(`RI#wyeSyapc6M4tGzV@g8%b%JI^Y7mOu@9a*mrfiC>+9PS-n)Eo{Me!CmVf;6 z_Vy<}_qx08JU&{gUG^_+500#S=U;x;nKKtY{D&VI29~{ptxtaG!xt{S;l8iG^DVFO zNwYg`t2(smHZgVr!wuDN5UK!TW+yekQ6xG`@WRN|G$ojlQ&Cr(>tMJMT-}&CxDSPn z)b$FeCL(hXVpU}|I0k_OnYn_5IwC#*SSbot$UoGHpeR|Wf{B9(+1-`MiI@Pg5(FqJ zO5Dk!TM=eKClysf_MMSAW1DrLF^UQ4C}?WQU#F7ZfH}t+C^_r1(QaMvqmZEBeIcs; zEA#1m)w@^By6b{0bj|DQ+WlAhBF~2P|K)Kj9GGQV7N;x_`pk*~sT-Gs-u@R|9gV)M zh;%OMOiZi0e3}Oes88%5@VwLp$O7Pfi6?hhS+9E7mH{6O1~JB29e`fUtAO_mz)YE# zi8HiAKfIHGq!JG*W7IS?4GdlqN*w0qq>kXuB?@6`nsUeL@4_R6lhQo{HFKsQ!JV>N zVd)fApsF6S0m4sV+h%a*hDC2by5O^*v%}v zXG`kp$jlV#wT-1StzLNS+$SDAd-vf(Z@TNHM~7i~5C&}befPJ1>vz2SLx1|=|M<)A z`Pj$*)6#&e$UA2r-#&M4u)4l_$I;>11{X~)VP`XuiC}c{#PadOX>ae+BafzoeM*T< zBeAK*D!N0nMTe-8Dw3t<(!u#lOBXj*PadleZD3`kuIj013apyRjM_eaO=PAHHbSgo zzS^WOBY3vw`GVcwjY9Nc0QhVRy|yjPvf`h%dg_Zrq*+aLcvlzm*QabA5MT zW$k%A31`{6SFLQN`NCU{1w@4AKcAUhg;ZJ8){0;P%-w*Tm1-7YFf?1KLYtemhSVaJ z2_{XuwLRJ08K1qBw)bh=qRqifSiEf|64;r^h>|J?CX!4{A;@Sr+E^VOK3r|Ap^g+{ z>q(seiGifBNv0a8X?G|4!oP0J70R|Ti*Vr``-P{cfI5# z>MBF_7%49Anw}pYoH={`@lQXv*W@O-FtNCrvWuyL%t^B*kHIuEI07p{ncdoq%&I|{%Eja@g6d{!n!86|auJz*mh9+6M4GZltb`(5 z00Njeo5K+Uh82fkfPCDhsMC42%c zU+C;8%+~8}Xm&3<0}cKE%NV7e?N&;5&V_?!J}gnG2+M#u_0?gi#2#j;?XzRva69*f ze;1|-u33G(cRa56;i3<;$&U&FF*+MUUuybXex@j zJ-NE~0TvO5K5urG*wJU<_NxvN_u4}PBZCk{Os6@ef?pSckC$43 z%3yOc5~3h3L_$PdzDXcwxVtNYqtqA%v$+3-s4T)BDfXR4kn;_(@W>T|54Xk7d zCTv_)t=XW8qMpe(TBzKh?2;8sasX~30@a$ax3&4%GZ#;7EWi0>FMHYXLveL!EyQp5 z_OJiOZ~3Or-2a(>{!9PjqaXU1gcM^K@0@QY+X&U#v7?7i+>tz6MJ_OqRJBVC98bMr zW4g6{`OInE-Aj|iOip3iPU@DFAa|z-FV5VrL|G(lHrm( znuU^P<_JNWoFKuhLpmHifva0cI#*#1kIfJ<>U>2|7rUBIQtv*c>&%Xu%*v057&%*{&SSSDGfhd9d)EPFm6XWpG~ax7)5eps$pAr6PS9 zh*&(3136`L4n)B`0MQUAhSq6sl6UqG&RyI)bI~VF$V!dYfemiv({?f#1cRztN$=x8 z3iDx^NAxI>1a%QIpC)LU3-uC6oJ7+JGO@dI>G(yBI)i6*U z6!gZgdF}Un_qV<3-dAj_uhpX(0Y>L!{-rN^PI6{1NeorAtmG7= zAk&k2h;6o>v3>-duMHFX?Xi>Ta)phJ^1L!wbhN)VF=jV*>Dv6MgfNEhfg&BlO?&C}V2Si1vr?cZY zm}PK~x% zr15O*#1My)gGr2FC?lRdn`P^?L*YcF=mfYgPz$0ss3DR~N&56>D%B^LnFK|HSjv?I zRHSN1Aa?JygHP|yGRU;Vo{V0Fu` z6o^PHYjDa*)pKAnz@TLbP#`0X+4@+$!yc@ z@ylFjg^{0)oR+CAR9;=Cd3qkq*s8w!V&jg6m&kneD2B5L9lKd!_mbj zam5#A?MClEllCH-d&}FkODUdX>mM&92jIExspm_368`sd@1@TP+PKQJSXk)_*xD>$Ef)oj8J}K?`q$0cSUz$XMX?v^}%!?5!Pf?;UIxh%GF9W z@%)l|@A;Yk`sWVac{E5qd}w(&E{$Zcvp>#DaVy)IgZ4|Cn}4x&>C!YG5U0_gUK&XZ zXBs_!@$zzAQ>1B=S56&!=MQ}6C*J#ki(9*OsFo_(+ns#o{U4}D!jfx?`egstH11>$x1EQc3`&fzl%-#fJ4K{hjLXIU$Y zto_2=?SFN}2rte9&G72kS30dA>LmmFX?n%tc0*kLs(F3Q1fS`Ibaf17v#?CGKKr$o zE<#VtD_2bOH~Xtta3|(dw13@$;)`j_v&-+2UOP%khpTtS`pwp+s|=$nzdENBQm=hl zBs&ELDkZ{+OGu}G;N@`h6Z_mZDg3W;%UwyQ5*+IDIc&Z<5xm3uXBX)1#1slUk(e}@ zR6!ySM}sN~lS|-aN=(_xg*g#17=S{VAjH`dyD+*cVB`kog1c+Vxk)hVLQK|$Je=Ij zN=Xzq^=#A$$1FS;f|;v33Cp08K}_amu7!K1-Z|M!&dw}KZmOm_h*e}(x8x>uXp@D2 z1n5{fh({RtB>iM4GY zK{k>CrHgqh9LmS3*xCEX5U`y3ex>9Ix7U*IwV(0Mb^?+;C)`|e1g?3(k`!=-A?K3M?0RH9(`&>M{9zMoB+_6%7MjAzJSkpY=O;QP ze!Ti`ATO(5QSI`KnrR7?WdSXJ2Y^f``Gw#@l10Ut1)dWq*&F+zF)D|Mx>mx;{&K=3 z|2c8ALsx5WYX60tLM=SzbydM*zd$6Knkpq^_)9!{>A@k@IsO%+{a7dFq;WO%~MpvcS^ za!a>dOqa@D>+k_vp}QhZ-)e`rD9Y|1vTlw9HuDbo0!vvfx`B`x1T9Rlt%jqqv$ko~ z<@TA+f5q;(V+Tu8EFthW$2;}9uVP-CMQObKoq$F0jC#S7PxXTSW$~YC0U3m&`YjwX ziK32m5*gP~Q(YZqcMcK(INVnq3@PDevjZAFN1~P8q}Nyv0n9MK3tCupc@lXc78a)KbE-5U!oDFj^}uWQwuE#Nmva+b|E-it$a$$B-9vA z0$1*qKgY{Rj=tz4RP6;Q6m|tI&uaAL9zQ{8glP4(1mKs_Buq!wCp^{+nXfuGSsGPB z%>3f4Fx4d~lWI8_I|Gd|tMn8DSGS8VghnHyumTcKY5ScSZ zQAIddd+N1*?q~JqCD&Q|!WaL>*7mQ!MRMb46dUqJ9G71>fzVH%kjY5Np)BW_@g)^&fH)>ckI&&Av)#%wvjRXG|I6tk1R#@Sa6o| zmtc)SHln(FLXzg?0)xzSV5(_Gs?pnW*cbF{ARW-Y0|(jp-)Vc#JJrUw@3r0oW7gcI z4S|g0S?;P(hFZB^xXQ+W>CskOJ zxNk14xvof3il`TkhzfI*XnkFXQPh(M!Gx}#gUW;wFnoCp6ga|`TUlW*do4R1-XUS7 zaNO2NMD`q3qgxK7jFVwyeJS@$%iEP?N#SHC=ew{#FoapATnJ5Mw9Ip&sO9ef)Fm2O z7vXsORkTz|RCO{-nZBH3vQR~jU$(mM97dKp_GsJ#u!M8Q44tsmSZTzpr2)+ZxROWl zvRR#ZeDiMWem2>Tz*}%-y{tM2s(eK`Gz03}@!E=?(s_c028LT$a zV4jVFGZR%Vu;M*aHpgmXsE#sA5I%-+M#X0|zG63O$Vd{IRd*>Bycy3?^7IOe8{Iwp zM04+iGQj-<5%H*_v)RLUFgQU;RDE!PHPaTlD*=SyLHj3=k};5$_%0&UfO9l=q35t0 zye_h4TH;CO{F9-ffzK!zM|S;G>-nrP4p}a8INn)`U>>nr{tkd7!oLJmWM3DyK1(Pv zvS(%-H+=gPI97MdBxG?6eYDj^)BpUG5*a6DVtMogqJSx#)2;-^^(ph9?DXnB z(DM|}K&%Dr3_Fr8d?^)F=RX4i?6fi{^PKFm7Sb!?fusKY$48OL%8iLg2^`KDkoD|I z`qD5#HB&5k>Q85swO3+pTE{3E$*6K>%D>8e?OuOt6JQ%1188-EuRL55W z+QV`1;HXuHC#~zj5$mD@r!t`5L_eouXncJAQ=2$EbCI;3=SX8^0{;EZ3}6lito)(e zCUjlRE2SBQoK<5=SQw#Vy)-pJDGX5&zWW2_I4YFpy#a`K5pP|Lq_Aj-nU?2%;@T2

`0kZTRfr2}iOnPik`Q5P>k)hB8*ssqC<=mw4lD>fh3kc-0v?&Gh>AnS*Ayq;Jnqb*2nR7$ls!9T-3|-EHt*V>=>Y^3z0ASX>0l|DM z8>KHAd=E4H7vYF#aOI}MeiUxz4Lyt*D7~ZzC-Yg5PAFnQzf8f6=@ZnDDhM)*^^EN` zYKcZNCZ9*w>hLub5kNlzQ9a+J=@J?WH7dHRT^9wZW1uTh#<>V!!~9St=GC)M$lfJ(yw zE<0%*p0IAFsptDhKGLII4U#sg(XmsS<~*cR7*gJmmO;r)M)M<`vO6Mqk2K38(0pl^ zN>UvxyqB_et-4gck4^!ZO66Nvp8kArR9*<0)a517N}Ty|5q93EA9wqyGyo>iEAuR)_P+*3Eba1kgg=QT$FVB#d{*t|ef*<=q5dJQg9 zP^(dCK*p*Lg)7j#auIVHo$%)swn9>{jP`w#rbbp}ayFZ`Ze zf6e7wp~{(N{xs#h7u4T=*Zb{*Z+wegcEd|;WO$074*8*SxM4f_Jv=P6oz||a zZ8ej_Ce6wWX-Z@7qi^;F`Z}1xRb#9)^)!j}mR)PyUT%Z~z{>`Wt(+oL0Fxg&dTOM- z*y=;#s>7X|4dtb*+*Mf!gLeXpMksY8M39W9G8vtA%B%`H_|3X1SJe4v{Z);qXefRP z)5F8s#Eg>T2)um^9-C}mA2S9zV>j2sE`A*x#{Z@@*3U7|)(MuL)QM1hX}XJ25k>@P500~PSc1*(g67SQkrxZK2#09j!NH$!|7 zB#@jF?>P#RvBGq@$f)r7EmFcG`h{vhQ70m3fgxPEJMF?pVaUz};6yNFUddaMS5-4h zI$@OM29Ju;5u#O#1%eQsKCahXmesWU9e^VG(fE7e6>JG92^6D-oHF5A@F;+o%1${~ zC0brUz*W<(=3JN7xN-tv6aj&~6F`TgeTLoTm0s(q@_cO*Ln2i#>MqNq%#YEF6@^#k zP?&Sr8Pup}J{7k7Np~f~Ql1Nha8B5nOxB%NVX0A6ks_a zhrRKC(v8pKJ^`LVm26L{$6Nx+hJ$L)xLSFZA*gnmb0@Ja&VS00X>N}U6;L(~%( z#4noYkipak1*VSzjIu6V=OO1y7;a9T5BZ63qOny6LbJPi9Z{-l3d))hxPOYyDV?Ei zmJGNSc$8Uz9$pn3R6O;l6iWr(;5jk(`mjHGE2D!e1ABSQYIv5r112Y_hZuh-4CJ8B zvu@B(>?F%5aV}*=ReDXw~M<8ia5`EgjJ=>)%EH5;;C z1dsr(Nx~&R1hDvyf#Vp`b<>-Yf>YVI#eH#QcaXdx}LqbJC%|OIh9P& zCT843QDt8wc!I{xogT99o8D{Zv-7soR?tXQ7zxldr`G8L=>TCn9ntoJngdJ3Jj`TX zN^1z)J2(nFML?#Yh{;Px5K)X9yq2gZ7kHB?D!-bZDTHI-9-dY?0u6CXA;!@|$uqe_ zELcU*#6|Maq@`~18JU`}3val>zVYe5w70$M%eJ|HCF`BDG$I@aGw{zQH^QwMZ#qw4+9feko<;9GM$MoTS zR9?ByVg(${Y~5g^ci(R-eBTVb=rjzqwO)hJ%32$Nc$dh_9Q;x*dE|;T0ci|=@s*t2N%{5!QOn-}$U;og%uSZdM{e0Yq?zSe zh)>R1V^&YqQN2Laym`VTY$pMdwr{AhiYY>6^ORKbOG-DhTV1eza_QBZw%VC<6SlU! zm+OJ4ELuD5s;+~!j@Q>7Y8kNAy!CyM^ei`iiJXTjo`QN}qO3W?08|)Kfr!}!`G|_M zjJ_11z!Y{pevk$Rf^W)F-AB(RMh=Om#8_sdF049B4y6tl7MvoEd^K{@G60*Fe9e}? zo0uli$iFI?Qi%bkC%}{xMgJ)^~*YEv_oyD5}eqKjY zXXvDQ{3W3E&Q|VP=u^tlFs1~Ck#c&-T()OE8(j1F*8fg486Qq1*r+ju{mGfLMHI{mzJ!JP(Sr(+=)zh*AznbH0H_-kgi zqggjuk{O$IT`%D^bmWmdy;HVtO_#NCg>?__ zQ>>sctDKb^)Zp+KzQ{s+t)~<6;JP(7v;Cm8aAKyJa^-t2Qr)C_%1b=q_;P>?X(?gn zFu}(;*L8x1S+Y!Zr_*q&i(Az6lemSOsb@Wqu+;#VqmdKU1qMn@2k*A2^IuMnWx&h7 zGf~?=2Ub#|QKpmO%cT>6ayD}|=*(zFGYO=g-!kvXEE%|r(l@|-Q(f=Q%lujX4nWGd z5|*-}Lpi!+8pg@(#`1hWo>{1FxKe1j` zrJUw65RN03ks_8kiXu^TI)p7ic9b`#AwvR}-2xowMOaHpK4ChQk~teA5RF7c%%j!J z(LIJJ>Huh@(z2ji`B21hqHESRay0PZ)TG_?tm|wex0yBZfR7&28Rtf`_rLwO?BD4U}{yLO(_44am10?jwX1T zJGI@fk~SW&(sX~@aMd4M;>8{Y2UcR%rDe8n^1$qz&(Hu|u0y*}ASy z>*Lv8v5?vDu#e&6yiq1r_7B*hu5s(&7+?#tFU^dc{krlr6H`<&PBROkF#v@gZvN#H z{KPjm>}B6k56eCIO^)HCk$$olj`AJK<00vGGN+-=fauAwz)gt9sy!ON3Pa&$=9UVx z?7kG9=ey(pZtTY>6RLTtk&?-gBieNhLfP-~m`{KXfFhn7AL;tl1nH(EP06lY_G@Th z;h>)Ik$P8|sz&~5pIg!zfTu~2a9-L(3xrl$Fh^7G2LJ#-07*naR0gdv-KI-vs3LanHpBhB7u>MbZoKJQDm2bCEACX5|Ms14+GoD}4LkRWb9wRXWaIBb{9gVjzo}97 z{P##Bnmm_jC=>hs17*U)=Vo8hV3gf;aNKzIi}FDxZR2eSM)8%wZkxqxwVCI^n9?6U zx68(M^FGBGm-H|T&@ws26}+&{#DJEzniU?jbVzJ~Ucu~xLpH=S*0U=Ite3O<9dtDE z1pP6`lz8;P|M0f;HvRwZwQkL_2@T&v1XrR+#Tj8drbn1vL&Z-Pu9uOpJI zWR?I{K&ijcmr2lb{gLT7{|d6K>R8C(D9ofVcy%Zz)sJW3ccJ`YYDK09IGj4)eACfYET>Lbl-gkO92~LAAS0UQ|zs4=I!j+ zG2_Nrj!OkO(NZ_Y1I&E7&PRHqaz6Z1%UoeCcy=%H8|B}vS!Oko$&>rS?Ehkl;>(D_ zr_@0fR)Gl-H`jM7)U!9y zVIo{AMvW45zucF<@DDcs?c1%5O;)PIPpT(?1Rkq&R>8=H<0xX(X1}WEQHmBBPaAui z7|nMc7`GnknjY5r+4f~y*{`til-1UE?i|nApE_Em=HR9i?rZl3>QYeT9f+DF7K+F~hre)D)Mhy$Lp3cBkEC>8d|G3S7 zs7-+$yl7@(_;)2jQqr^80rj8AAQ1_D!&LH9@}HV+ClLN*1VK1>^a30PAB6`n6L19g zn?1wm^Bzwu@pqqmv>KvXjiI_yY!pqp%wA?|O+xM< z2+RNEE?U8c>oU7))Dt)~52%KhaqDoB<&nBAMeBIL%4vl;26n-uI7gV2@%=k3>SI`D~YU-SApY=e%TfCqJ&7^8sYRv<+JEa2rZLB*V=ka zX=ncwTK6MyMUPI6T^l^C;&%<3bzagu$!0*-0+rWA%YTWe!f)gukuEgFM+&^~8ulXZ zBsa(L4~=d1gC}8ofmS#UPxRbHFmN)+8FV6YNEksw6~nQrOfISx*%I=-u+pQ%~VZU2Uei*9Pe%$fS;zPB~A|Igpy8L*Sh{1u&5&r8hhRgF6kiNY zRKRsV!9a36P34_H(|M1x#Qt*xr*tLb7ip^W3`?Z1r)NrMnU(&^$~3;N0O(Ewfi(3i za~pS3tl%`js+B8k?dsK5*|yFmXxy7w^Y_^R@`R@7wMN`V9`78PwcUFU+5wij7C17f z4T#QAgmBoej?A{r%vf(%hfS~O^3Aky;)eAHUvd*y>QJZzHmZP>zh2f;0rxn%IWUNp z*90l1Ne<9gr6GA0N*D^aq_S1I(A}xzN5rM1<(~tV_>{aY;riHujuv)~r*l!Vl#KNe zlmkT3>SRWeohT}5-V=fwWnwkSNt#)xN|bCCpKh+<$fPsLuB0_4V#&WdA^cV{bqfWQ zvWZf-xTr9cxFGkPyp95jrgRFX8Q{&0Ier-ZTDi8Sgdnc z0v6?s(4E;j?7|`(sk(A0So#%YL3IA1<&|KHukZ?-IwFaNh#!Nhu_zN1(e$vdDP{rKFdlOAOeAGWS!sR}=F)P*F-Dxe{`nSL_ z#kgXaT#^cnmJPfNYJ^TDvSvk}jc!e)~U>~xzJx%%!PR=sVPW`L?`r{4h`GF!6`NO%r-D9fWKKbD5;}Sp{(VqE0^o2 zN3%_NJTR2krE=Wej>Xrtm50M2ki@6{1;gwbC45Ph2nSAJ>YqC7wM9V*3yoo zYDrKs$xF(tbs6k1gnVQNeo-VcDdm1;bnJeOt;1DCUddq? zarAF^Y}np((_8GU%P+F2aqSAv3_S*VilfVj&YPBkW;wPsOM@^+nhmpxTNyb>4~|Aa z$HchYrI}sjeyg2#6k2RAqqqvY$`?A>+_kxf3!)h1VQ=s2wKmp!{YdI#!1_s&$0h+K zvC8)pm-JM|$8CaqKQ_TFk_U%5al#9e)1*6jRMYudlUI4wmB4yQaxcgJ78q?Cd7`Ul zwe^xmTY0OZgZuhT9YgS3<$^;vDp5MNx01ZlwRW}bS;v{6d-hp3CkE(#@a6@311iwz zZ1s}@#D|+k+t>(DrQ@MySTmIxlBgry zq>gA>3Q!%T(j7%fF$|OHHs6f z!WT?<0yd~JsRpOxV_hQ5I>JYCSF&qd<2Z@{Kgpnoe7zA{IDw{3qJbufr@@gUoEV>F z?*J5HaA8Tf_4y;GOV)F8Ox8CXILA?hd)kLMMv<%shSTj`GX!D~JR@u4BMv2$lrWMvh zPNgJOS=4c|^Inx@uvSh6^bAed!FwOHPVW8hRtXW`N69Ga zcy!aTnAowG*ilcY^P=*t4h-?BP$v~6as`-p%jA`Vy}m5!g<7z}QDKxGW(;08BtRlw zxCu+J45$ST$eTPI!&y#Z$J9-3{E-u}=yd)b>-G2sVP;p892Py#eECKnYM z73RQFc*-M7Vwb#^^O3;Wk30sNh$t5P$uZG&%HVj1Lx?VL3^IF3mCo;BD+u7<QuK)bLT|TCk?8wKuerPK zVFWf|Z3icq#;r0!qv7sq=LR{wUdWH>epTMFA(Xg~K59BDEK^jg%oJePIIO}namV&O z@Y!l(13fm(Z?Lb&dU=MnRdUdJaFNlDPjpUFsYyVa>NJ%;%Lw?u^n^_@jc<(DJ4UCt zOP{>gtF$C7Xeisj(~Wvj)>H@>9aA>6$3uDE)0DhAt63}jwzF(7|LuEhirJm%6}`Lx zv&J|FKu3=*EcXTYb-|^wB4Z101gv2BplL&^9U9?bpM!KJ)DRH%obDN5W}<8Nr0wP+ zp;Oka;zSW;B(}9)e-s9}qoy722Gv>PfQzF@O*UDtjth zGA^R0SbA+&BbOsyhYJvUZLpS+YTlO9bmDXXk`xw+Ckaz<88x95IWK>sVOFm5MzE1U z4c*-pOwiG+I41oo6AP#rnv(x0RM4lyXq`C+oC_tetiHc9?1Jr$T4cCjKVJrtRSV2VjL!{!vvcvl&}#^|~(N+-8$g+z2-@ z!rKuvLc{HLhz4T?_a5}p7_`wKom?6?sz4t$g397de=pBNkJ#|&0c+<1piVNKE-&mD z?4ZHt8egX8_YG-}2}?V5iff2HH*x{cqV(Qst4Y7^zIJ0(hbMtK|9@cGrXJdDyUyHb z18dguW&$%sbOL<@U!tqdp6ZQ38hl$dXe0DCx({&MB}WEz+o5g~)TM{*(A}|m);9OB zbVR4&h@C__k$wTuV4qd@@m#iQ?Ns1nK7$DJFA$n4k_SB5I+ju@pe|YIc(Ke9%uj5 zMaxkFT#}0b0rW5Fd7>y~rDaxSX(b6~L5njv%U*^Fj>;f!Sh3_hTsRa62{{Gjy?!Bk z!=D0>CPMm2gQwr;W&;EduQ%~ipdr+2^| z=3yy3emO5>Pw48U=dgoP`evLAOh`2_fNXKMRLlkAR}{#ER)G*<}LKJG$v0Xd~I!@Tl$If6(rK@Ikx#?)&Utzw%AH``&+aMmMfI&pJCh zZDN$Y4NMhl)7K&P7L2T1#Z8i3vF0op6q)qV$L|SAK^crub2Fp%NzA*34_M2tT`a+n z|Cpv}?`Y+bo;KUNbAo$w?ge?HJ@q*^+2xmBXcu32u5I4B*}8exqlYwYq4Qp$gD^!p zjgE}jb~=Z5eESZ&{hw~P|9ku2m>sIviovaP*21wB?kHt3+F%>S*hrmo2_1Y42>k*R8BeSH-u>l{Jf7PkcI*9WeiyTmWY!YFB zC0~^$;zdeE)zl^Wz^i@2DS8+W0JmW*mb5~>wsFLmQuS{ zObcSsw3>h#VJHlruBNh3hSpo>+H^C`Fk=tvdY^e{m;KtzN*m-!JG~R)Wy<}F20y7> z>1VjZ+=UOo>@H9$Uu96nEbC6HkOeN{Rh|^4^Bvf-s>9=jIP>F9QHlEOhrICT&dQu> ztAmgXp%kF28j&!mvw~zKd^$?=@T7YZ)WBC5^)#`QzH7yR-SxTq?KyA$aXat&t7uFa zQK^Ffz0dsKN6qdZwwAShHm^0-(v&$H^~UKq?%BVe3wzkR(ZNC-<*}3L_5J&XZTR3$JLjrr+VgIHm0fk^Wp?&C zXW7~{D>+U_=aWvmN*}APfD}v%rcS`ZssZL74p{#vvqY>TR=Hh} zul0_zOtANWwQX8!y-ewQ87+L540Lu{SU%`rxoNDQ@-$0lRcrs$6^eyQl27lGuT+=i z;_qcZWB{lhYB`j^VCv0Q8lLo~Bx^1PR29R)7;SJ=vgD>xcm$g}B_$9sF3KdI7%Z zFJk;yI}}`(e@(GYd>>Q2pT2j8y^RruF~Vh%k9`4fB6P8lSizJmILK`&CEQ%9vYzou zejH7x{K6cLMS+%|oYPbjG^l{^bsRO^QEjQ1`UXfLlsaSzDR%b*_n<=3DR4A^;A=Z% z(3C`F56M=LQxoeXEi+ZWZ@r5t_)cmPzaAJY^)m|IBPu{1y%H%!W%uNW%^VoDZgyK& znHuh2!Szk7|L@szx7mu*?H7LO*X)KHuCuewJk{2+DX@zvV~?TMF6ijZ)6lE)cVYKz`sTc>eS3uRrxS_N%}29^^e{TefVnA!Y+Q$SZ9-cG!VQHVv*@XDiy2x0LJZ zl}gwO-nlR?3>u$i7GXv+Uo_z4CG90?AFtTn$uaBc9H{r$Xd@Fg=@BCKsZ?0LVmzYK z=ltuILElHv5WKr5I#J{k#PL$&oZMpxAl$tQQh1`TuM9_1Mc7eC$P1!QG@?8%MMB;d zkzWK@%4dQ-9NZ(2c|=YKwTSkT1hQ+^L0V3Jm*8>PI{=v{WxBdv^iqOCjx}&esDe_+ zBg4X1#C>ZWOvqi|P{j$tdzuM?(#D0;-mC1*{+< zeo6&iC>gDwBS5xf$4n_))U?-B;H!h6X-ze1VnUaqDjie}v@$BIFzRjMCN(Kdr|U^o zy$-145~fD!$4x;>FS<>w?x&Jw$26C(bg9NCT?hL+Y|pMCf@-#(c>T}YOJ4E;-{;y(T9qDg8A=q0NAvj49fRlb!-qRK>M6l+Dl0*gCF>U47-HcJ^7P+l@Cr z!~W=he$+nxr@w0}SD)=OOH)+zz2k>$^1c}x+H#7mK@RF$Mw%VB*njU5LfC5j=b5?L zUYWAyyLVb2SMKVW-oAkj+sA$W#*EAx-uCNu%gxWU3(q^#dV4s>kDS}U(S02%$Lawn zJvBp>t8OhNsGR8MO&17yidY@MK9&=%yzBy&gHE&SZhW$R=(qoe{naP_z_xBXpGSW< zI!e3VGc|4pcav{cZ{ViO9_opdSxTv~z|v3u;7S|Cef}Fet(}>OS(Xk}R8;}ba{^^} zbEmCr;Z~6){EL*zOpETFU?XdF?})W@!Z*{Fiiz@K-q48EmB&S3?4EDsAVmFC{t_Gv z$JaMxlH?$Hc%2%4qAn2@Ggtv~z3$_T1VwNBQ`vTkcrBt947=ClrH;&rX(@5)5ec~+ zJFg+(W5<7dFqgdpkn%{1Z3wlLKkDFaDWyXpBG2X7Atg+U%32P-&^@fe zRx@ONMMI48b8&6wG}EC#vyF5yJiD+KqT%0LA8$u8as zv)t&q0jPx)RY?o7t{}4z4m<6sY;}o=pI=6%ngNJTpNKtrrSz)OXdk-&A)DWSz`E#w zG;~pyefPveu|Geejah+ zERGe1vYRFeq`J98ra}X+&cGm3)6cyA$#(9UXW5gly4v3P&fl^9dv-GYJYXYSg4E3{ zz~loQFWa`k)^RzE-!=!`lj;Z(P&$w%6)xx5G0z6LhxS?rX|li$yurbC+r=n+%lVhu zue|+rb_23sNr$eL#$M?dqhwN%!l}IH7qXD1(b&_u(u%{*cKBzw~vUu~;boy8`=1)Joah#pP^9NNFvn$~Zy6+9R2xxbXI zx=5&*eFkfR4XxtYV2%g2&{6eM1hl8^bY3PnMbzKl=3|gWonp}?w|8`um(>N$)oEALaM2`K+w3%PsP9UdZ* zr#j_jBL`aNf+fR)C}c7qA&O=LsFB2fKD#1B#3YzPomi1nURZwR88I?gSyV2(5_b}v z3aj9bS0IN=k%1DtE{}z`B9nj(h>ISm9z7@A#)luToj%nVT7 zVICRIJ-D}2-v$XW{Rov;KKR|k#X^;l3G1iQ)z+%PfmRy-|FBzM`IGjJ-*|^T|M|Dr z%H9s&!L5A@+Fh-))LPr0*9?H-04(ICXe#cCr+&nnO0tD**iG6WK&7hN3l-lMT?PcK zjYebhhL!fCKlU>F$Vc95r=EU}4egue+Sq=ZVHDfVj`F$Pdu^C?84 zb4LG?QwCk!8Pv(8f>rD1X1{~`_Sh(|_9<^PD&=@J-JM(3+7x-Lm1O~4KBT=1zJq|h z3;X-YvAT$eIM*q7P$!~|3ynJ2Co|986JAnPZxRpH7pk*7Kg(n43=o{>W0gA3!^*z= z$%8HqQd#wUF8cC^4n&~Pfo8j$LkZ&8VNFJ9P6ZlL!pbU_&1^@|btDRSHbA26KZ8#^ zJw;yf$i@aH1r8^D8`8A_cR8$))0ZRUBFuWpdBS^+0Zw6#jL?`JlreD^9xAf0U>P4^ z*-J79Hq+ABRnWbhVHVuo98ZNxD~2cRWnIz8Aqb8c zZ$4U5E}>F!sk1cVqkV9lPjJ}$@0Cvz8<|vTddEYRlPaQI89_oLf6s8LXo7r%qktZb zf}S26+C9t8Z+2z3Q_;_G&U#>=-L~KVE&K7;zR7;^7vIbj{Tbd!ceJ)KbwA4{MJ?*U zCp=3|FzfO4O`pyZ4Lkfd)3|GNJR%WOr}K(jv)y>ZRrVJj zd%sXF4z|)G6GhI2Ce{@X2 z#hYjKloveBY0Oo!TRAgYVNXbJXOrFf{WsfZKJ#JQJJf8W<5L{<p|28Br;>fo}$arTPL=p+q!d6A-1(yXEzrqOAo%vU`VnSmwCGr(^1p&oT_#P;;3iw{Fu0CAVT7Bz z>r*&jsHwoM*=0&qbpYirsR%9GmR~PeD-7bPF-AB_R#}yd8C0jcyJ$4hsl!?p%Mv+l zS@>{)7UD?)&30{23y=!5_)7?A$pkE63swUbU?E06rvPG}0)I}#$nYuur-%#2Sz>QI zqm!UJ;zz5q_8;@y^v?w$+6dUdMuZQr9CRXB(~{$naKwA?;~~`iCX@W;pSX}2sQ?Ta z$u6Kz=czIF5-y}HyX4<-@JHpNKl#gro*|4p1R-1m*Z4>yUn$wVGr)|1_>~xS|D8r4 zK59~_)C`DL~^oTyH(kGaPpE`Jm5fVG}`CGNA%eFu84g1NT zd7ZuP=U!!JbNs7|xauUp9BZ;oX%z4L!)`0~7LHX(_Xb~b@yzBNJKy47GeQD;XC`$D zw4@Xl2GLwe26C6Y7Ut}ti_fulz4z_*l zNCMxRo+Ov49@h9rMs09>)+T1Bt(Q*J?j5`A$3Z{v*wRDbb|M-8%?McG4H$u1mr?J*52s^Xx;o;h9gh z&wTd%TnwqVBbvBV0{=a{33&Go8-8fJRoJiKS-X@p%4@7h*?74T6;0rIc<2Y+}!mP7=h!Ra`_xN2kh+NYs(c253gWI|T&KmE4Mh;-(U- zeGtv;hiN1K_fhz|p{Hxjy^{-HMSgd@82lg*_lqE0i4qh+4*Q}=HaI~x>XnQxk1pE) zWHMPV(3Z(?%zS{TxGkwX(zs+|u1Bp|z?Ss*_yavHAOB!$A!b<#5*e^8)?_X~WPCDn zD1aD4wi%Y38mtZl#wi|Bt;r5l=WH*{&p|2U@TsnM<)V~+p^uRImL^AMG%XsEfKnbTt=R2b?6u{J8WZdt3SBR~MEP+=r{^{I5h zLpes`SK(=iMRlEMXPm%%IA8gkfuBP>meM_}55X}<}`PLCqE$p^3%xpgmvgRC1rMCfTe&P z`|UE;r@|nm z%7)xFFP}U^guAh^P?@s1dCoeRSC4U7;!Emp$m+&5IqVn9){Fo z9j(LCuWvODi}qMLL=&O1nuX+{l`K@Jo@a#PHLPPUAxiu#0SzDyqoPS6_~(&nyKV0w z`-lBp$A#VDIL$i!1-oaVmCb!vkdE3_O{tBtQD=<1;-$R9kol9I%&y_B?BpKcO0mrF zfbj)4It;kvQssK!W_+==RK$epI9}0}kQ|tOC!7ouG4Y6J`S%g4K+p&u>haSo(>ai; zaBR+*q%zjUDVlDat1WyHg95Gn2T3v{Hs)|8r^B67ndNZp;jVG z&w`xnIp$dP`f8j0m z?stEP%b~u;oj*M`JauJ+I{EU=3|XiZXapF%14W(#L_b#_jx_hGiTPl39hST(EMu&Z9g=Whj%Byv67UlXvlx zcjD%x9YId2=m;O6GDjSV!lHiw?QB%)ThocofT5jDRQ##Yr<(DfUujB3TrEZhPFtd1?Uu9lK?|fkLYQh~|1S!lgd%Prs!>C+OJBk+s5Z%)fdLs?+ zjzGE*`}o-(R-i&YiiaFu=kO@F$1fHSi<0v7vZ}~rS(MR86d7eH&azNTnM4^kr-k=i zv%iGvq9>-x%d^^vO($R#<%qpIeyUYyD(4yu&Us0%atr93@BCLETeESKtefovPqTPx zxD=k(4NhDDRLPuzPMJPA6u?0DuLm9u#kWMKpxNNpy@`QBC4^L9gBc2OW)f$a3ug>I z3!uV@**i6==D_jwY(`fB*Ifuyrqp!ZgKf6&z<%4g^Xs;I&z($tLW611SsH&;WL4y< z<5`}j(D8fG%X}wxrK#J&L@2an6E8(Xj?EwsREDFIlZ>dS{23kga#ib&2ftxI`l{F3 zEziDLtGB++>aV~NhOhN1v?PQh1sUBU}TJ?`TQ1JzlzZ_`At_$w`&Q2HFb^1eb>M8o__p!#!_BsOl(i21TVXl%@Tf2R*c#M z&A%d_%W3L_k z?JIj(z9Nt6c0$US@{Cp)rnzKnmL-IoPs5iy@>5>Izq1Js9!o4)*P9bfTuL-O-DNxW z?yv{A9BGCQRL{zo9jMZI(B{|b98VNe+zFMRXhKAt0P<{z3%la3DnUUD=m0cSgEfG{ zPby>MJ-j)QWKK9vIGaxdy~O{L>@>P7PIW3FBzV{wJ=J+wc8jOaa&qB~w-`{4LRNmU zjOVVSa8(k%-&R+$*ZGwEDHN{IR41!nKEiKCg#`zB6?0m_7PoS2ZjMT4_n!Oh^6Rd(*S_U9?R_8lnElzOKV;WF>lz!M z+Rjp={5w<7Vl0zHRNk8)SOVi7CoPH%m9=Ob-2@TwImL#kNuKBJ;Ea76Yp<Am~FT|~GP#uLY=GyFp|g59i_ zH<6~1t~>4JFMFAte)={>ut=0PwM{$!$w#_q$D1)War)@h#VGmH86{yO-I>Y5tfil# zlYlRv{uN$vYDVS4(=%l5b&^6*CL%mJgY5M}8zb$Ordhl6(sS(>DHjiJ|96%Gx~y3v zcpjY^XX7H*{K2nA>m@~bT1CHgnpY^LG})*b4b6PC?H{)}P05#!i7HNn*~}g!^%6W@ z>Tvs?W+|)I!R*|~^tbFqulPRuU!VGb{q7%r(BAOh-fC^!jj(;_yVkX;jSYjmWJx^q zG9uz}c_^}eVHaVx&e=R&5RP-_3T}EfmN;b`I)@&%B0ez%{ikZ&FDM zOM_i*ImiN`(U1|!gmV1LuttB$Eqf1VDkL#h0(wIy+=QR`b`*X5r>c`_RQ@#bU!Vr6 zuv1tg`6?Ac$6zZD;0)V_4cqLk?|i*oe$5rO<+M%yz|Ra<{C@5;pM}sEQ=#hQP%*Ko zN#gYlf!>{}F_c;HtALq5ouh%A`xUR zv{adEqn|LeUQ9mHj_U=cr>}qNb#~>I&$X|9^*?O=+Lgp((q>k0dVz~zv@hU@FT**- z@7<54y=Sy$Q0wb!%*X@4f5^VIv?@jhe#mqzvxo zm}(Et4!07X`_qTIt9@)dHW!k=#GwAPi(mCvJ2N9v+s@c*PkY8CbbK%2Wy+`73!d{# zt~36u{l>4o%T{)uVx4^*Ts(wq=`^b|)S|LZS*}h`vk{ScK;lf{Dp;3=;*E-L%Ik7; zK!#>}!pvaN%4T^e{0Z+El>Exi385s7V`Rs9E@Rh6;yWime3rihAR#D$J(073(6dqS zLJ1fSQ4xoOSKM+Dt~c%lTF@1&P$XauPqbu7VW`5GgD|sl_Q`6u{eQf{-OF9#!;CO? zjPYz}OFy#*5KFvCOI{1=Zb(4!l~9*P6rK?H6?D9y6~3a9si$7E{<$m&Wx@|rIDiNqdLTwB5A~RX*g(d&8CCZ_S#fR_34=p5mr zb<4T-HapPNZoNFk+}uGYZ8|n+KKB{Vur;ezP(725-f5F~Rip7wh=b zlPU}$v<#Nb&HA`ShU5wn_eSOH8weaV{r%=)s5V-~avp*|)xPC%htG zreGzB87g{pP^Y;mZk7?RHie}m!~Kb;)Nvf=?FPLcAsJWLxK`!zgeEf7$NuEcm`Q1| zQ#Nn53obw3PCe}uZt3fZhMIK98&^|;pyhN*WmcVkgzH@b6;3%z^Q6qUjnW71PJHA9 za#*AB)G<75j-6)8{-R6HWhvlR`TXqTMAUMd@>=%bom=>bO}AWzbzsQu-#KI( zwyw1`>-%lZ;5l~I*{9hVr*E^@z3MlZF`4Ber4E~B=}ea#=@_e)0CwH`fNfp1ns+X` zcy&;2VmIp`Jxj!5=}<@o452wV@pk*|)xZuWdMUMNxTW+#~8rPa4a)5sv<`#a}zb zhxYEWTVMEcyY!+92wx``#Es(2ANUG81Q2%7cX{aJaTi~}%0MBZM59n8qf74$(so?zF%Ehp*VjKK@tsxzGMtK|+QWJB^2GI1kP>vaLMz+O~JnW>+%`V?CQ` zk<3V)pC^Qc1ZX}u#wI#OsOk)nlzm*AeBT{A?HzZ#0TC!)b@5wouXx1^>_tEDT)XP3 zOKcU_Eekg;V|F+m=iFiYPLE?U=_w}$YoLa$uklT4%76%l8W-e=(~;I z^>mhh=l$@(0=q68>lo(|D4wIrL2OxcP6I(*tb}9@JJUM<7)WBcqpLkEyvaK=GP+Ulj0R9Ts7p$beeyyqsJX zf^JNK8dKo{qSw%}MW%GGVWrXqnA@BLbHwy<8fAD6SD9UAlp4el^g*VIlRIzMES3ccw{Nz z%Obw{sT@aHCcG3E4_O<4kljKvBkFcWU0g`A(AQ@_`??>qCtpqD&wIz;<$;}FeA~P1 zCw}0qcJ`%L*tr+3X1O4a*R{x>gvW8f1vJ!p^@GT#=-O z%$z}73qZmwY3_ua5T^cIynZ~3bKqms_P1aDNBfzdextqe$6ie1f4iN!;cDBm`f}U4 z_DOcis>^IuTc1@YY0ikYD%y5_W9mR0In)vZ-+M+it}~?D3`5UWp1$>tBCsZA0lMiV zZCG)!ZCrJ}ZCZVrZCu@EfB1**vgbVSdi&M4|28u#_p>a(hFzDR5{EP_(nwSHvMSF< zS{Q7px~-3`J8{jxwdWNH8#oeMO-Sy($7P?>C}}P|3psH{p=QC zQ!>k8x;Tiupohmqy?K^>4Tq?Sa^@^pP#jckGb^G|KY2#COE$4DLL>Rfsd*cxGjQ2; z&$R#kGRp2LKVbiO&pm85)TBN7nVc86SC6sq);`kRpkwLmQktXCn#9 z6Vq!kb3IIMS0|viy~kElvGg*sorSI+%@M6dG=QZr3if4Bzsz^xRyHIYk@V53h$9Cn zIW-0)pkTRIE;;B=O1k4G{|?L)aB!^T=9{5tcm!0q+TSoo<=ZvTWQPvk!I7&Ur15_e z=hnOI{yn?x6+ifM_Q(JIJ$4}@c0GO6kNbl#-r5Pc>PzYP;#?tGJ6|H%ILlVl&Eb;#%q|djxVm%~Zr>GqXJ^ zKC_%i@{Xjh?XyXbS2X9?M=&|aDS}i+3xDJ}g{Q_=n+A0gpx-$`9@Luw6;4DPI>hYV zjnA>I=dH45o%wS6hr92xIW|pp=qlq|UtlkM;g7O}$Mwqas8b0{!TIZ*)7(%wHOxH( z#K~pmWh>&R@FV60CxyY~T#{493wZJ;pfjGlWygX_y`gX}4E64hsVzsKE|A1XcFTNa zy$<*2mJ?wQ04aZhs8os9xIwCog2hgr59NAf%mPg?ets$-6UzA6E?qu-~N+b ze$&&ry^axns`RvvKzEm`(N_n;&;NTOd7#kF0)sU`!BKEKudt1^@FG#g|FNm+5L2P} zYhy3K=*Wznz4=mGziu@_h$e~%`tEOb*sFr}aN$+*mDzQfB?E_Hrk56QA*3H#=Gu+^ zNpS*Qq0WtUwD!YG&QFiI!QIf8E!D_GB0=cFNNMYnnFDqi}d zgMgbJmr{P!wZ#j}B2;t|LJf4{LpVC=AYMgEecX@{<&d646C;=k8&0(^;oyOB>mKN| z)6QLMFF5NJ_AmF`=Q9m!)(zUrU;c7@@3lUbC$y9xnY1wzp&Kfv4~<$gGjfWb7*?1H zD>IQ;$yOXC?c`iI3XuFEn>;h%kRXG8sb3w>H6XLOHtXpc?K-Zp*kMFaKpLCI}Tffdb z1^F(2kE_Q`aaOQcJpQ#1<(yFphJXpfu?mCO$`*9d!7kaUa+{|?zvGTO?LEK60wTZD{(4%H5zhnVzj4`;^aDRSaPBY?}?*y6>Wvi z+#xogwbP+n(5Vs{Yl)eD6$-mHnsQxd6T@D?+gf$O4Qu7wN9@c~&ap3i@x%7VfB2U+ zbda4oF2hKp@U30@p3+#A7i(^EU#yfz1IIfCm|Z7e&sT|tA49~mFlE+#1RFMOc5Dy#;EBolXY_LHeztMegC9iSdJ z6U#IkT$jgMVkV3wKqE(`xCyI_DJMzrL{ZDmi$>dp@&X`RNrHuAfYoq?s)@CLxIrI& z8Cb@4r&^MDeNf;fdRcQ^JX6kGsbis%C52Xa3#)^d`XqAoxj=}8L!&QMO*j&sqhvnH zXgTl_jp!JatF@@)97S>^veKM$42q79FfGvI*DQc!q3c9D(ov$VTeezX4;3si-LYrL z?EWuWJEIie>{jN*xy?ogz}^Y*6B{MN0(a)#8d@8h`QGG67A+oBa>b zLWgIq+k1meJ`zv5B3Zpk=1g2h%3Xzm{>bo@U4Fw&_QBV`+3vdgeyg(aaP9h)b|rgz z%pT+-BIQkWC@3@dt#Ue`syzs`V(oM#4;U#(yR{UQ98|Alm17&nT9Yj!WW0=&b$QOH znb3)#i>D&7%gi1FbB94cxd$N2&IOcnL@5(xP+6}NW;kT$D44SG%fMufOoitJ&-pO3 zP~bLz`7pTv36G zSIJ2%xSn_^0P<8IxJ7{4ukZv6IjRv?CuG+{yX>PM{kZivZLx7iuyMD)_6Fdt?bf8H z{?z!Zu~38JWEsIVbIPQ7UXtW2_!v9jl|WB4C3(Q%H5*pQ~&5>8%MG zI&}=lj}fwEWC)4SQ9doF$GG&Bzm`0a;^ zpIT8-YGpa3LgQTV#yM!aFBtZ?_z<0I%~(ECc~&0t2h1A6QT)aybWHYq`{XA-ZwGl+ zxPx~Jwr)Gc$x)*4szHFlfKD11I1`GS=s_fLRf|T6rQnM%s0CO7H!3-1gscmvY;N>( zBG?s`#N!gNIs%6c*h|Ue2)-X{r&=xfSch~J`Yv0S6{ak+te5>dOuf)@jsci^*Dm0a zM;VD_H2CrZKm|ownXb$UP{0$qoJ7{G(lMYFKe-=H2~UWw9}X$ugcg|k9*duXSMZ%L zMa-2K+hk4o};S_#40lp@mGN{^5-GDet#WJZ^%BYshVHJc6K}Pl9dobnb zVF_0AC6n7=R4J(6!&7iig+J5DlqC%6#We9P)z5tmos4W0LOC3F^hjr35=U7~j!^n| z{A)Z1$0fUjoUH2b_y~-M+;#W8_KmOqqpdk*kWFlo7jZ;>z7Y|dWZldZwnqC3!bu=3 zJtga7H^Bi`sq~+aO6h@YeG??okt}@eo_s3#ROo0))-E^YEz0{GckOfO1k>f3r(*VC zg!Aoo4*LQA*>>&TFDm|OWzJ`w4S?ytUS(L;v#SsTIh(?k+?5v!r8*^CJ2eEIa36oSQm%UZ1Fs7)XNDx) za>nz#1aeK3A^1Z4%9;8pHrbr%B_!8!#>K5htB#ApA-jtY=S8|uv%SIFqp~{BizztI zi@^bb884uPI{;Ncxsr57#V&so=HT9&{i5a7@g;YoGF{Nf1Np@$fO?f9Z5l~yw|_+s zkQh^#E`TCHH)x7o6?6n0m7UOh$Ft%kK3r+4G8%pn5>&GWQW?W7NBa)S#6a)~Vgu3)3XR=9hz+7oYpX4Ew}5TqfJoD5Aj%*L z!8Fh)gW4@3G=>NQ<^c?Z!Gw@V$UNQg+%r#m>fi5QRqywH-~RR)?!D*iljPRk-}_dr zT5Hv+RjbCg-g<3NS@!G(yt=xN<#cAzt)cA8^AWn0dvY)RRVCO3l4zRH$1W~Mdv5y& zKKOwkx*5<;K5wG{@hgeGW0m)+8BDp%oz)$c#3Q9GIxq*XJ__*eBbnKB!uaFif_$7CE|&v7sgK>mx*zX&G~_^v!H)`_*50TlwIJ9%0P@K5VpfwIy%7 zsC&yW#b^QO`n`s>UxU0IJV2!PH|Z>ub(Qz(*I7pAC0U}BWCuRlBdb~mIqh(h!+Cng zYu<8}00#tBo2UtP(N%$Yw#K=MFJWf!)-eBOodeM|j?<~OACU%4{jzq33}mIu?#3=zY%W13anSM8JeBcGseB~{M$3M9n$i5 z;|U*$Y}s!Nry;~yMLnnA=XV!#bD0jF*=s%}D~T&9&}G2oCzQ$0BF85$WAAx{ zLMQd{?6iGn_jX1(G8!E&@(87Oj6^VQQjzEhJl}&i=trgYGHR%YKfb3Nf9eTvC;i3n>MKa;3e(7)77m^OSJ)@sxR83mjAzw*D`*|cUzGq*34cEHw zxGL(AK#wBDU%5HRuPui@+-!afw_i`)dqtBIz7FUJLp+|38aEPtj-JQa7-Np%HI1Q3LpPENs9|bYJm;Q41LF)cZX-kPSRXb z*XQBRfrVBcoyjbYOpW)h(?6tG!yTS`yU0#CI+nuYjvJu7us58=D z!HvWruqbCwo-Due1K(Y4z5fU^2%lrlIvX6j_R6beAV}tU$XBo$EpVyo(WQQ~T&b?W z!O%@n`yP9;tnfbgR?af7wCDMRsxoI^gXuPQd6tVm2fzR{zxfI4Ns2uBDNkf?K%)kR zokkou*rEGMpB<4dGyI0^x&I3+``cu8o69L~p@n4%&wGrEp;;>c^#bb1Twh6&LUP|t$o8k&qEV*CS{qYds$_Y_cuyg9NkTL~PH|+XjN& z^V}c<02C1YV0s7lmpzYusJ!5Pzs{jFE-z1Ovl?MlSg&w{LCHh(X_AWURYN4MKdTF9 z5*s!{G2w~bf}W)2Psl z5MQGjM_LrRwOV=0%gZ`5kyPYx8C{wn-sGJDhQ;B3vk@5sg7RBV`OhQ^r~ zG2YqhBYmRb{AHEi3%E06X*?B z=L1%AASt@DE;^V!?9#sDjyn?Pr(iu--H#*L=||sbJQ)Z$rSr#ZuO4y(?j{=m9VnnX z-)*mNbM$mRj_%PXdZnXu5M`O55p<)D=#VTz^q9?)+N@!VfOw9#VX2*S>=-?G{4Ss7 zDf{;wLYFT8y8%-?z}j1gWZr**>R%#5FOMMRp4es&v4zBm(;RHG0@i|O&U#?@$+F7F zel}R8?!i2=8HM6xgk zIKGBIfMz_id}pGcb}%xS_Bj0{Hjybf)Ue!VP=|y?ZwR^78a9arIN?yiRz(|tS|z38 zH^@>2%80+#ZW>{m6_*w@k)03gNxcTAzM3R{ZBXRcQmF!PbpT*@-8aVRpH@Zym%q>v zY_TuFXPs_tD&@iQd%yesa^{rB$M!tRxpvSKhDy|3&2w$~>oqM~7kWEtC#-kk5rahR z>=(=3_uLiu61RydxO*{2BVJ4?9Api*nOp@R-H!i+2{H2K#{}4w9*wtI2%) zTqzF+M(m)sX7iF{bhXG?_ZbABHpWSbv*cXJ*Pi%Tbsg~e@fv2#c@$J0DtF#>Gy@0F zvY#b-#7-yW4SV8-!Ci`m*k=C(tNjXZ{_q%Ih;XcuXXnT+t&bued+hOGx$2Y^DVN$= z4M?RL(>K2pl2rz>w{RZ7n)_|6e8}p6ae-Bhb$0D%ug)MFaFu{-Pv^OtHx-0H8j?cK zI(4DU(Ie{4tEtpk1}T{UpwCJct4)3qwteZkn&p{rrK-eDFyQLL)}sp3a1brP7EJWK zi)<#W=3zYhu$lB`f=!_9&_NKR#?kn-x2DuYjiU#;UG&uQ*+l^c=SVbJ+=uT#ZwC`-HXZ>k%8wT z$J{=8?8D_t{=_SJ&;4j3)>#Sa4}bau86h*^b_XYI53Mg>Pf zzw4dv4)1ji(^)eEbm|_btsGVUo_M>HpsQNTp0K&s`bS+&=0Rs7w83`~k^nIivGmE$ z)VWh{`&R)C&2^9{f(!i8Snrq7xiFpKq#z)Z3d4d3$Lj@!H~it=JsmEIbnp?>AAfcB zMopO1(6(z!dK>&Y0!G=1=$1+PHQmFVeuw*9v{5=ckX;eD^X~Uq3uuGu#;aqIIQcOYG4%APexFKx1e7!_ zSk(v3AGB6&IT;Du){1+6iO1VmM3+fUU%KfQno4jKfKb+P^7MJFfCjWfj$>9#r|d^? z-G%JDeJyF)fL^78ZjtAr9uVVl=3bWlkC*>ae)sL~=0kdLOOo94Z{E8Mb5c?dakF=T z$`=_c#^hRYU2X79i4FFwJaGR#<*WY8mz9&}K3EPO-pfElQkz;|1ymIE&YFs=0B%f6 z`O=X1$`u2GttGzZ#eI2+0(#t_{1-XdZiCYS_Z@NYbgX>w7kv(|xZM=|6$gswI*+@WPE!_OrtWp7mG#V3 zg4u!?g{@cGH+NSaw6u$K)^GXEw?KC*U&y3PIo*(V5zGE#>{-z$M&vVzv8n~G2mdez z$m22UsRQyY=sV$rTpufMGT}AIT9;J{;Y;Mn&z*aYLUn#kP(2%x7R_+0VbgA@X{+Q> zygT!X4?+O}zWhKaR%V!6}t~jdJ2fXcJ(3#?;uJ3Aj1IsyKRs8g zY=gWr*%;G~D|)T8ovQ1_FclXbLj1FDmWPd%to7SKW_=(+)D*l{7#``o&2!LhIYR?m zSE+p_i7#%7`Gj)v^r^D2O82jz>|^n1fWsVD1pIRsJ6#;~wDc^=o~7V)IGvHR`4~Dj=h(?r z74+-M$^M)9Wbk|5R{onW{>t(yK7qSTo!a1idiAXx#>M#YYnRPF?d{}gxc(Y?w}Ty& z3wC61ze$Qpx%mI!dp}VA-+%pva`(-*F#zC1J%DRRZ=%z2c;qTwiE6ju|D*1Sc}3`JDu7+eZ4m50iF z3Y0*aH@MKMVN_iN?}KbDjWKN+H{fc+jwsejEgs_}5Jp1fO+4X_GxnQsr|#W(o?j2x zrZMB30i`ksmm1DA%nk_ZpnwL<2G-Y@*q!|=d{Bskh0FUNd!qcKFaNUg$)EMga_*F; zlwE}*J-?g2c{3ZmF0!(~tbhN)k@AcG?pMnD-u+?3A)j;{&d$tdZ-{nIp*K<7(Shp9 zZ*pm*J*MhUZTgy-CjmOce9?;@F5mu-zPUX9#Cywun^rl#Ryh~|@SHzy1W>jc99~n~ zjyf<1M>{Kfw8MMy8Q37~EbPZ@jDxlX9_MV`%8%KzZv^C7I32upsI7X|!xpC}Zu08n zA}0ZEx=GN}^0KCMU-^nZ_Z8)y`|m8vd?UigSQj{>!M9Dau@J?Ni?o)tFw1@VCw^Ul zpkqv2zl*J(AF0Ot5mR2;+ne9~+nlTSq3p2FTQ02Z+_aYu0mTw8QFJg^WB^z={Kt-R~_l3BO3cg!;zpL`P#Tq54%}%F{nV)0K6T<;dC4FC^zxlw`?tzD zcFOzN(mmx>nI+9Iyll`0*=LtGarh4}|CIyGe2(6|xBT`8f2sWTTi#wi@lzh+D}mj# z+n}UbN@VMKoJy(XTUhtDtOboUqo!QCro7W2qRhO%%^2s4zW58ucYOD2%U}JU|6;l0 zw&$0_w;U|TAK{a)=wY320xUBSTJwzxI<7@lDrkaPE#PyoeDr1COCMlH%k1|I4@$uQ zcyp@VvmE!)$*(gLUUooWN9EoC%qiWJ9j^ldY-^JPmJZ#vnom+c`uK;-cYgOjEPwcq z{2_EryWoHUoP2ws>9W=o3UE@8q?W*->OM1`z>n%^U+<%~KxL1IckOjUZNYBp7fvW-VnxNKZ1ZM91 zU+^SJ2Mg%Q)=-&htGHcWAwGV~234iuf02~~Urm)y)vyDJMoYYIT5{h~nB@)P2-L^` zH6RT@U?ZFgfK1pJo)oX}(i0N>>GJ4Fjd^w0)ZN@nm%}B~Y#GkY3-Ucv5vRm?mI60i zE7SBw_VCSUOk;_`w9NOuJ~SX}W_5=-h~0?Ao#8WtD`Deyjc+qDOa!Cy4jqm!h*o-lAMZs2zTdU*?&;C$g3D8)b#r$xed+n;pv{ zvy069O@h2o25DE|V7Z(=ewIPN=akoe^>>x;|I4o_4}AJjmhb1CEnu3LaLDZnz@F8; zW$pGObgbu?>Df@;UjEHbzM*{Z{VdfvQ)Fkj`N?5D#44k+qt=8(HF@nmrtgd-0}ybWA9S|1~<(P2yY;-+N@G z96q|I+;o%||Msnw_kQF}<@A%w<#n(7{_^Et{w3uQAK#(m*-wb=Vgt+U56~7ovC?wN zU-aASh6c`$I+$Jimr#7gtYuSY;gq3uEOxY5e(g=aU4HCey|z4X_e;uo9t&N(aIq}k z%4S4g@yoz?C+6^k#|obnUSL0qn*cn}%JvLj20v4j3Zk>!P#kcvL_PeYr1~zT7~9-( z&pY>D{k8v8o;dXz<<>j)@f`w30d6Fep{sY?gNw#;@2rrgr`ti?rShk%_Z|We{UmDo zqPRUTtVNKgok2LZ4V911UEHnT}wi*OQ#G4*H43L*zp zo%lL(pGmya&47E*5r22Gst3(9$XJi)VqlfDCJLx&x7bGG49f#<_8+~qe97PXrt-$W z_lxD|D{d)kbWqdI211?JB~uSS&3o-4$#Nuv8|KcOJXc=)suz=AcJT9olIg}}n)9VX zE*G!v+h3NMVQoFdfkn)kAG-f&`N^O8p7JNY^mF+n>lg89V`npT&@{#i%+TC~Wz(jz zh3hi*LjH)_6P&1~L&R+UN@u_=SY!$QRCLRgu&?wT;uFeW`4wMYKKUgtEkFI!KT}@) zt*;^OmLAC3Rkd7tI>v^vGd&)q7!fA79>iaixu zOXz~mUmY*-dgW8+_^j@e?;a`RlgihA-8Ys$_C;S%KIP>vEr$=&d1gl5OOr)<258z? z-VTux{wYE4%?47m08N|!9o(ecYqQ?25V?@{)RQO5zx_8qU1=%54PMr$=$jZ>l<0s1=>c_?bGR(di1@ijb8;jWYmfdQpMZ%`eFc?Q#7+ zA<;lbUEPG$gmHz47?f7+1xAT|QW#GN%&y@oQ50o>9Zz_9EoGefA9r&9LzPxIJ8)-S2>w$oh^HA;pEB3&zAixg>Uk;zbENXKkXHtR6h6fzJ~Mu_mu}8xVPN* z3HNcoryRYNuS2@z?rIP8{<4Zf`J@ii(ODEWboyiUwW7V04b)W`Y^Js9=`1a86JYV_ z=YIA-l-K>>KPV60|B~`3j{-J%gt3?1;s;jvaFwzl(`B7TPmNcaCv;8e6Dh}HegI6^x<0%l<)oae_T#~=^tm$$>BtAwO~4OCsP;5Xa=U@*W|(Z*RdZqjK?x_S1>#Q4+ofioDD#N8OijK=;Q3Ve*R zqrcN$X&LW`XT&(Nh6Cwo%n?F;WJDg?rVsEd^+XThlN7oSoUY#}oad}G8ZMPS`Piv) z;J!at{>6{}Y_!TSDaW2Kf1~`!Kl}0W*T3Pb%aL35GCM~%ZVFVG z)=AUKMnPS@wW)2wcHkvtHY0XHNNO9F7 zt=EZu8dfiN3ssZ~u4wuNYfB8=4Ay-H%jNgp@t*SczWF=K!PUFVQ%{|VX`N>k=-}PR z$tF7w$+}{P>@Fv5Eu2RL{zzyOo4CNa2KzqzCySbDg(t)#hVBHZXzx9_MrJwG zIwf+8oP(Db;3m;XC3t48Ga9FNr5qKg(~oK9!Fs;Ncpqi{)RWzp8SQo(nXBlLgxz8+ zB@9*c*d`XF-MWEgs*~D@UrTSq`RRFgGMG8srbOxK_xz;Nbs{i(d~<6rnOP^VO-U2Jk497f17f9fPD)tZDYSIZQr*4rn36D9S0PXq?!O9e>WfRtf0dKl{)pa-D`DC%i2kF{ecsKm; zp8aLxf&1!)!^O37n#UK158YAz>|gmm%NySCMrPtZ`!}0rm}ZI2qUR@@9+A}s&}iiq z%Z9sl7TlvE@4X{&xfz`>(_b_)2vEv^f6sr<;D?5K0r^&WP0;VtzxrEVQyzWKo69}- z-pr$bi@Xg$XL0ipmWlV1;&X1$0JgY9M|*_Tobz|xoQ;;JPpy|1KJU}Y-+%T0US9Xw zA1G&d$9|c&KsH#(ajRV3$7cmAJO81#d_5q@S2TTN!~ugg-hV0RW}FmREqKBX;*1N7 zE2SRWu+O#9IQzD^ed_L;EkF2A|5^FI*S)&jf6q(GsnhIfL58)JgXQ3Z50!nVIKp?x z)D?KN9|n%u7z+QK>?c`lvvN}8bgaN)V*z_r7$J+izi(@I30J>! z4+1>W<G0K#4Z5O6>N;aI&R2#V^2hQ|*^cba@Qb%B_|)yi&IEw9HaqNkH)U zXL;m@z32Hp;ZVR^pQ{oMkY#U`I7uh^<3IK<%HR6CUtR9H^WlUyIn3z{XB6yt_=V** zze~X&Mtis#x5x*C{2Z`#HuVsC(@y%4ShK2iRIBOiy@y0G{Xo`bk`2%OoIBAv|L_bm zX=}?WKb?ALYTdz3!JHt6#^4}=#N7$(zX`^KzT@q5AF?4_ug{I z+&Hq57`08rpl!#!5(%y~PS4V{PUrIcn|`XT5ZI>0ORyLU1e{qtH$JoAZFoDezZyAq z;;|E4p&}TU`kw}^R==HyCh(9B!PdYfOv8ZOsn28iNB-)q9C`&$gG1+krA8r-O`f~v zvpmd*%|jYX7|@KQ(QxVYT07;~&vW3r4jn0HmiF^r{W7ZnXUeU&ES1%@)8&tS!GB+V z^56b!Im@h3rMRK1>V}Tm)|>{_nV+4wv!OmqR4>F3&Nv}{VLE4>?tO6ZkikTr`%kp$ zDS)2i{{9a>QNHP$UR}QDAO79)y!$`3ocPF@tO}e#NBj7Gz zlOgbZ_wq98YFXlQ)gc^b=yHD2T4wJ+&dzXjPRH;5l5C`{4dcL}TUy!*P-`{QR(<91 zGBw!zn71PwP!zu%Je*`=-iI>_tQ#hY4q&M_H6pSQrw~<;eiOMm`F8Tuu^u40(R9@7 zdhcoX`%L0z?#wkwY%(%RZw@lRFYPN@_AHC5Ps)9ca$&t zvM($DAbgLnGJ zpR`7bi>t2MV=Wbfy#$5p=NDKlLkGbr(bf=IyWGWZ{n%oo$M3)ML*?7Q?R&~!|7(A_ z+<*Tkmt)6Hae5KQI5RNWy6>)X%k%CpD?Hk<6Ms6+1FW{#^cN{(X0g5*R*7gh;PT9^ zVws1Qj~R-opv=t=kD=6WxLIF)c885;gD`csTYIH#GIeMKoZ?yo4KB~_WIf;Q7%?CH z*@BLRyAqy?ITBU!%3{)P#Du^Zv+g*PB*Yh5Tloom_k2&!O0R*uU2!Th`tE?)v{Dec zOvOa89o+9Dj45_=;zy_x@0H?BC@$;kET`nrC|ZMK$2*Rz_*U=g`rS}BzreVpRTKVRfSXrJ5HSrEd? zD>EV?1&;IPMEU*9RpX8bU z%gU3FGgD=)|1|nty!*~_?}3}jGGB{xW8!meXAP+Ly*x|5XAc_!AGi~JanKK)>ti1{ zRvu(f^}XNwedW)5)z_3a{QLjNBY~4CQyW-64eT~X>KmYT;T>irU@YUtJzT+FqJ$HR#IezjCAEa6+=Qzdj;(hm&Tkm_Y z9N`tlr)}{hcz~}-`oSn?;SLPDO^)TwK857Wl*kkK{^2F-=6j4i&gHaUTh0c`K`A`K zYVA)r1n$HD8y$F#-U1l0Q_s4|_@hIB*#?Y7GRog9Oa{B`CQ@ISAVU^9;Q)Ys@Y`^%VfnVd|6S#czxtbek?}m|S@8cQAsx3fxj{5MMzx|H#ZLj{$@&%v&ndMjC_{((uFD$2ypWwAa zzB53Fzjp6k<>m)pSPr@AkNqcCR%hmCTf6e>kPfK5W`iE`V3u=S2ZGS*X&o>~d3iU% zvgX2z_Q4~nb#nHn6!kHgVIhsGBLLB*X(38*cb)$j*5jt`mqnPuzNUdL^HfIW$=6`> zqP7VL(iP!tBfR#28|xeZwbV5=ltfj6;DCB>HWQ!PEwS*q*Yvq1c06y~k=a*9-=JUKKe8q07Jo4BXHf%lL z34Qtcum76z&<}oI`HC<5yz)ms=QGMDe8NNJ0B5o9+kddm9uYJ-Po`?QxG0(>e_rVm zyiON#;`kY!OP?-p{>}ef{`F7(O!=`N`UzqlFAqNN73C3L5%W-&6*dB%Tc^`{!9C@! zJ%@6<@@2Got=05V$KQA9_p*`m?jyIB4|4?c%KJXZ{*H6yNoL{u4y~3uZ+=O6^|yUv zdG+`GyYd(R?B|xx|GdvGFMa95<;bA}<;YEk*{4#SoxO#pJ^1=u-S5HRj~=%E@hJvg zeYH$~@15^1KlA#ZFF*X_KUE%o&##mR?tMu)$z!F*pE_RluCA6f27DJ^^kBLD{uh>m zeD0T#iH6?{rzQAwZhkl`vu*_Ka;1&vRzqDQst?>VN$BmObvU?}Nf>$!+*_~r)nDo2 zho@}yCk(;(Jp5FU8c~yMex>v`OkQXU6iHZPq;J}VU>YKH}>j)bJA>CsCr4f<%Cm19J|+xYo5@RCQx;SYNPCFstWQt@dblmtpqK~!T~nuy?gq7 zn(h3MNn8#7d@d8{NFG^FyWV-Xh(o@8uRuvSqU<2oRygNT5}@H7;)vmU46 z%)zjKefNJO8%r?dH$G?XxAJgFJTnz#1eTr|-VMJhAu~ zN33$p>fX(AlA~5v85}(CzE3M3dfWTUH-F>T^DE`^{;NM;KL3yX(ek2CehD4Mk#fr| zH*-4Q0p2E9|N3XkJKy>rz&KcL zKYBl}PTt02fU^uVI3Q_lrJUj`e}_Kd!E&2}0N!1HZsz~=irbKr0}eeXRS zVDm`X!wlS4Dxdhs#d6<0FD++Joh+~Y?r-P!J>}lpUsnFipZ~)0sh|F`a`d)a%1t-l z#Jl>3%R!EhUS(O|LiN3V&+PZr(I?m+^28Iz%G=-Z&hpc*|Aq2PZ}^c2dSK;&a^HO~ zDo;`7JSpO>kG-ri@Mz)%50|^|zL!rJGwb)87Jl+~wrXB&R;@d%C|PZm7zAWv9G}Cbt`eHWYk$Yej9Tnm@7m7W%C5m>@hdqy~{UCxt>lX|~e#a}JH>0QcgldC1rWo!ak|EH3k3e*HNCdq6hoRx}V zcwjYz>oOw2bndC-61QKk=spst&lSb95hI3Gfb`=MU&2j&KYS3PNfm*V?m9cONMpRn z?C>VEvU>ZS<*_3-m9vjLT9(hAX4(HdOZFR_bHEn`mtUOa-Z%WhTgw}M;isCQ_mt21 zoL7{ix8G6@9oo<4LcY+4GS0HJ{N$6z%LkZ!zWL3+Fl6e`%Ja(IcYHF>i|Ge0ZZSaM zZG-c4EIvwk@YZtIfkS04Uu;`s0FlFf2Fm9=SE~UB0jmtcZe7_|R@m$D_~~P1=|c?g z*ynMa_wtwcg5J?v?&Vdw#d7-md&;+d>;E<+@rqCT{PNI4?9#vewsMfK?k%#+??^`AODBG|^q_Ec0O;u#_DzV`+i095@{OPQmXrr2sT zHPFhS7M@1iOA&9yo5SZyL9M*56n!q0PgwLLhLy42Ye(Px6+Z&dE^IQ@v0V!pRN>Pq^0*VLje@b$8?MrLBqP&} z5s25vnJs4E4wClqS>yZJ7jWtURs-%iTb4fjk+Q&^fK8qyZ}Q%@v!mOO9xnU${{bdn zcHnOK`UM!Uac{0;DgT~N1b;uXM~))q+3$(dBt%QFgx)Ta?nRDSJ$U#Cr@`@9fn#hp z&py}r&sF8q0A?184IlErs{5W-PVv}g?c|eX^IadI^W?NXcI$8OxrsfiE0oiVD5t%w z#B7vb|Fz%Z_xc@EyyfVF<)I@lT~?BNtf$A599I*tLFf%ZM@kGM z{fx$wu#mdEC)@nIjA~zS?dUW0Aku%x&T(Jgw^a7=0DYOpunz*VNr{Fivxo5NIdCQc zZ+qa~axLlHnC%>9qu$<|Z)4eau^c;kv7CMU$+FCcj#k{AfBH;0d!AW3jjgW+-gf5$ z9LiSrSJ(*qwm>$D(f;}289&;0`q=rh$yx6nN9#B1ZD2R=zNH*Ibg10QGva-0AS(74!dPY4f<3~>t_3UrPQ zy<411u!oOjEgU^WCrq1WZ)8aWP+@6f64~%OU5K||tpBpA61I3r z!@u1dSWxFGsH3&$Yjdl@bs@Kfkvcf(e?Bi%UaP|qCIWnhCH>-8X;4` z6W54mZvz61rg$|K5MRx+hWqlJZ0xKn2@=&c#({@Nnc5(3xt=YOx?u!=oTbpSEFa#@ za`pPM^`szoG4CJ4N&Bd$u-{`9gS?H8Lfvxsu5#{{J2;t-FY=u@!P@|A z^y9l07f+sI^0~@64A^(8?|wTXj)5Di=#1?6ZUC0Ob~8sa-@>P+_wOrv4;?Nyv5#YE zc~4me561a)?=>mcL9p5m&_go_!5&F=`PfM=OrP=hv;URetoY3UPxQpZ0SIa92YR(Z z^s_|WU3AcbZT4BXpRu;C`}j`^$$gYCHRtb%KxTV_<>wycdV$J>rrj9Qo0wo2(I>zo zq5#sFq z2%qGjwvn-x%TH#wq@6-YA{BT8T(_9jE8CKtw9CZ4H|;BfhxU}U$BvavU+cPWnPq%5 z;c0HRjQ*fufuBYg`aPU4zmM6V@oXqt;XMCCdgw}v4A!HseWc*K{=5c4 z@vfGGJgzCcZnzg)+5adu?;yifFO|tbJ=(%GbI7vH>5z;?(oyCSfOQI4db$Q9L0`F} zp5=o<3S~XClOG(|4kBQw)b6AA z8_Dhd0AN-dDhNZZ-;=*WWr;@HJXoCJPTC4?NM<%XM9lHX<5KuNjX9)qLDhPOs390W zGl_NHNxugq9SIa;>T&fxvy$IEQ? zf&lLohSba28E;S5jP*gi9Sr#(yyQEsBL}-YuJF4Ao4%%zScmv=t!X=Rm8hzZ)@QVxS94y8go zeuG`F(2QdT26{&Prrj{>K+2kKeGM>-C$d$> zCUWCCvy)~1D(nK!csU0VMKyyW-r-GRS^Cc>)R=8i^OHb!gI8Q5XmhmV& z^2P*IYclLe27lVl=)=6VHbJ5>;gnEBfWKq(6z=s8+yDcBu9{{x822WI`XrzFWU+Od zku|JojmL0_G19^rhMf(q5F2FCR}MkWDa`)F6(jURZu8erCfP<2gNOiLK%u{lPsOf9CwX;5&ZN_0 zcH`blb2rkSO0()m&7fcuy^2u>HlwT>Y{0J6SRtf6JjMA60yAlBqqtoBHiG$pLA=2O zUgvFP^KXdL(6+nuKjs&g5qq9}bj${?vF!>Uh$=Uj%U?8LE;V}mtqn(Y+>LYhx_bb+ zlinGE#1l(yv7K|BA@t?MNCMvp@6PO_MVE^I0A}4L9zaoNX4{0h{4*F;RkRm$DH-WUS_6x;W@r4vM1t&gkP8FV+@q4dFIlpo`U zk%a_)C+XqcRdY+d3zd5h5U1FYzwP853o9DG5q2dQaB9q8U>OWe!xG|R8pEeTF%ZEA!16wSSda~UXvyHO8&Jk2%3H*zSu!5ACCn3p z^2YP$nptW_!1FRb;@6_<2)pA}el`G|Th&lYvg<9w@fwrag3lKrl`ahdx?JVB+H-XF z8#X*N3O+yG%lqzI`{{&zJutkg#2E=&p-Hu->tdunnO0e<1Xp*pvtMP|c7q1$ZU6D- z%YS*(`_e#N9hc{@pVPocrv}`UlKnW=BkN&$;+hvbWb0jO8I7f#d#(Mg-nGz>b5{yL zScAsSSp16&04@;rXlhwI$gmo(xdL&7w|+P!>;wcY>6@Mq3&VQHg zH`D;2cV3s&g;s^@`t;r**!9SDj1j1Nr|>%PTHc#1JzaveGLfcHR*Z(yZWBPK0W!G2 zYNhOi6EuBt;n#GfKZYoS7H#@|#cs*jM!;N|1#Iyi{L;Raa_&QqmvvsBs!Lrg0?ApqT^-Bku%FYwM~McgFVYF9XCTEGu`N}l)&j?Z#dlPzzT9Eq`@fF- zGh@#nBupd6^69m5YK>Fu_VH>Qox8`{UVPr|Wuwg?OewONYC3=A@mF^!*T^&*3U#^bXbEfWUprpNR5Y1?LEOSuR!8#B ziLjT~0v$ep73_5$@9n?)=CaI5mKQx-C=7__e|WSPT+o{nWpELoi#kj>m}xW&JJ2zK z_?K~4fU+}(aav-{hIghM#f&BBei==eRcMbRs(V4HSQB0Js8IsD>fQC0bfU(I9_A^j z<6+M@Lfkdb8Z=hGgva0$HV-}^TpLf4>_W#3TA;~OmzSuthTQ-WAsLCMBG(bOlJyEb z&Ci%RnCAHbz7cQubZ*s0oSnbRfVjYdUf~WnOjAJwFNw>WZhLqZc>W_#lrw8QCj@qY zeE|2~b_buc<@F**@@awOhjIJ*Q8Lm}4r?z-@~SR-_O6uQdEu^jQ|1zEQ0amT{?5|%Ld`9Xc%>|F^rFCB0r2bJS7!ib}HO#td!X6hK0c=04 zlSXlRV6D#y5?(BOPn|AzfV*dda}f6ID^IbqxBlT{Yy;r+L1zCtKb~~);$}H?|6OI# z4+lArH}6)pq-9Z^=WZ?wktb?35%VCnw#i#1Md0&py#x!*$yTC4(JHn1=WtG0Rcp< zMzkff#DsRF@R7GsUh`XK+L2?2q_UhuTx8>thK3!sIIEe)Rmnw|!w9gOcIpemO)v7m zIKxU3e}JY8)q#KrcKp)wTi~z-kGM^mEWdkqU10A;&dh)F@0YWjepfsemG7VXv6~D^ zV6BUPNuDOg-Og8FejP!~%R84b&z?A6Uh&_)xV+}azpK3P*4xWt9O3#+U-x&)PrdHn zmzR9z1LZ8=YTwZ*0vi`M*f8jhXGG2G)Ene?i&@YD`9QMvLr&kZ_Ejhw)Ojw7oEPyN z>|;s;8pS;4$`-TYKA`kjxT|FgJRdKd1i4A4$!8_XB9F{I@cxtKt^e`=D{uehchZ^e z#Bg3Bb70ylt6ZAj7Atg1*3piJsb&){ccJ#rcFIfCw?%%QZ0PDiJ)5H1wN+92i=1-! zI7b<;zn9M_L**L>Sp}r+T%#T=-+izwAHBI;+7bAEVZ*m_+ zb^#ouINsnbBR4I^&xe=7PIO_oG$ozf{Nk@Usqs_SjyDF1EZlql89$3V8x}`5PRuq^ zy!^UHEr{l|xvrBTtfvctZ^Uy%)v7FFLEVd8>34)Z-GGbCF@sn7F>m zGXd%E0}6>vL3#3F8){rCc}1#~(()ker%yc^cs~u@lka$c+5gb(}G`8LhWAjnG>&BQO`_Hls8yME*6%eVaGo6AGD9?gD(ANWVFEwBH9 zA1{C4vp>5Wd*U=Q?aa`I`aF%-hqgHP{E;V-$=4joD@XV4zvqr}@XT6Sv_bcoDsnIE zU(JbrOQ+6cFc9&YE;7*M9cgD!)dnvk{BzMCwHnCxAGG^4_RYSqgDpN8yv~V_o7(%@ z8XI64EYeYK>^)pAuy^L{nNwwX&t^HpN1?v>i$A@*{Ima3dEaA?m7o3YpDqV(Vt~+Q z+l%l>@XxNIEe8xv2SU{HY^t*y+n{?<#{>6;F`n9OqdM~FVLc<@j;Pw%{HJ!iwO+DQN1 z+cIdTYhW-^&yk$E-`Xw$wl#4LCHl3KPd-TdH1*5Hjl-lxy>%rqg8**UWm6JWm2j=) zqdx$VgyZ_XhJq@3+-zLOx!k?eCq0mdboIcrjY_82C(z=9HE5uT7{w2wT~37S5x@Hb zfU3@#*ILpo-xJlUQe7>B9;)FQW8_5f&0;EoY&uE12Xn%HV3AVlxD)6lec>g>h~LN? zT1D%1HzVIEA_6|=^XGikjuVh5x>UDLTtP!*O{Z44yoM(g#8joqgN7lMN`CMSKkmcs zUK*Jt-uX3VYm<(#@#k|W%sQx8oF_>5!XvoQoB7Zft{I4Z@uVz zb02Y=tuv#jDKGjv&sPH1-QaqTuRGGg`=*O4Lz{c~V&ocoU{0LLAYhXZV%aIKyyL^H zkYQUqCOi6qBjwER{ipJ2fBi3%ul!Sgvi#1;C&~}~FF#yf^vZkrRCHZlpGxmCfnH$c$7Yjnp5$kwyUDUX1BJ&Q zb(XIo!h4;(@wc_ihF?1REe87woE*6K_M_|%;PpU0khO=lA)QY25sI6(mzao50O{SKQJpv$3!|^^JiFKraLcCru-({ zojBughmY^Zk9ir_X#(fcanyT|(V;MYK|!7=76uxi;&+BJpRli?-M#Mm0ANr}6q;^h z(0{e=DKndD?*`gvTa5#0dQx=*Zmg)E`Da(+D_|n?NcONgOS5KAmcN`!FDn{&^bh0a~wL24W0@Z47(znr= z$QA)Fb5T0ZL3e4AzqkJCo65iVrtd2+d(|H-r~N?7l{oadv`7Pf4jwk1j;Z)t;@K=+ zf7zrV^i2m-@-cz=JjHv@TQrP|K00te1C8Gz4dEt(0Q1IoVu|OWh=T)pvWaS$IKKz5 z#0O;d^QE>$8~dzIG^L}{?9BGrt%}J?0`z#7&{=FpzWoqZ9RGdi;o5u;V*=6CZZM zPFdyIuz?jDys9?Aexx%o`AGjdu>kIr4( zi!E&Ji#_BEfuy+1;DPmma?o#NV8ae5pO%x3y!nc*WA+@()1Lni{K7igtRQuf_5#_+ z>-w>C<@mV|mW@42W&JFJg7X*4A&ToEAs1a;CBOu0utO4t6 zNK*T(05n3{n4M7&!>e}7R<}C(9!24mpxPys#W2R%?b9^!6U_#)8!-0;BJyYQEdTj4 z9NGn3(1Rb=zH)Ab89EU?e>R0cF@VCk4G z26h$F=<|7Bc1CZiIJ8ka72?%_pN%yi=AFBb1uQljunm%Ws&(*NgxzP5=dZq9;iCo` z*0L8}daw#VzgBnCSymL(kpl6{qb&WVOZqizYX=D4ZV23CGw34ZH&%2HtcD1*l3J-?C*A4dqLuBCVeJ#yxi7FH5DrvtqMlc;?UX6Iy0{6xl01R4b zifXs1OoLN*v)4%5xvz;?ni)xd0T!SbGl6HZXT+g5J?ZN{cu%SL}h80PPV2*1P$<}Ga-=t+agm+ z6`FKdkRq3FOz0NSr?k%&oE}3Mw z6wE-v#~aRiePrWo6v@aFoz4?{xsLQ=GccF0e>w*k`b;y9@OIZ>VvVrHO(rVEz@u{; z0M(-gGkAn790yu#1N&HCJH%NMluJ8e+ON~4gR|3jFrcEG(fb4DW>c5j#nBcuM)@#g zElcnE5S!QpE^;?Ddk35|Mhd`OZ&F@DvkDVjJNJH?BpB*OLnWCUx+892gzfC1_W5|& zbIIE=El-xCCArLiE_sD^3EQzFUa_}*CJuQl``90wM2V41c(R8laB@tAP?p1 zuglc$U{~JqpLHFk2;B)Ahe!VK6c3zE8nT2%L}2{M5=wST6|P+eo4qi(M2c;t)%&-fV??Uq3KMqq}u@QU?+=jwL{kMT5ku7&aLsj+5>^0?+uBXPQMU|b* zloK5OYBORd1@#hNjZt8nF(&5Kge<{Yz5@zr)!2#=#7^GmLOLO+D7hvXbs&ox7-BPs zBrfue;+56TXyL<;Geb6mHkdUB%G>{B6j>W{2c|lcQ6t)_dWteVn}RglB&Yq=YMzakrbD7L23>@__VdB z?IblruJADE+vIb`ZvKn>)Uk-|k;R|6bCfbZQw0l3~PRn=c|NrZTjC^idXM;g3R3pN6OE%rtP%;+#_ayxkI zOl<%p^Q9>E2W*@sFZ(DB9t&(SAXwOkrX3{9W0Y=q?i3a-es{Cs4xi=O;G(Z=oa4%d zVOE8FbE@(iGwtGxh3Je&jAlT)8QlE=fV$#mJUy`iSYc^@g!OoF4HAy5O@yHVF}`;?BJzB3^CTVQDSoGEn7W}u zZ$nhs0q@M@%`ZWGJ=uvzrnQ1vcT}X6SIqE0cXg&O=Sm$tn-akd8i}5&)Mmu6^DLix zR!5kQQVz9=6Kbuu3~W@Wi>j*KpQLGe)u~n) zm@Dd>JQuI`!xPzk5$~!EZ>BU7M8DNR3H4ez931(or)Qh;A!ZI?E)Vc;k$< zoGc{ehCWJV;7C!padvB~))OVx)vsn&e*jl=kw0bbVLb;ga9|HRT zu2yw*BA~CKSFw@~-bzNSnTd2_)-o_o0d1^g7F_*!s)`$|lBC>#FSuF3GC$48`8YXY z!=QtJ1y=>!)Y#M%e)84H+h0#-3^#tKuyMLkylttQEDxT3PdQ)S&LhEBmL=Y{sAW!u zI&P&Lu48bwj~LN_vHPCh%I}&aF(M2gwlGLRsA;d4p<(^ipiw7;z1_iL;}1y~PIDU! zA^gY1Qj;0dkU!CtkAeE@okAiyYmxj}8HLpzxDgQ5XaVp&a+(oec{xKxWm66th-<^2 z+6tm~Zb=ufBlrfYz@#H1+?a2L40Kf?BZTHvyEc5)2&=C1ct8lclYMU}6uj2uDv%9u z1^~d*C{Wqz>`H#sRo>P@I>y>EM$E-?3?=U0Th?wrQdU0lR5sEjqS0-;rR;ci+m0vR z7Jpd)GBf)xY|?V|epBnFQ+4TFS(QJ7n*{XRii>39No=yr1&@tt++bu9)s|*rV&KZt z8_}7m+oOl3H<(5m4+4l8tfI?2f2QTi*a+g+n1^rGJ%$p9o@@V0C65lfP7 z?3LDB23LH1RoaG-n2|q1SG<}5{5@JeGBVs@VeF+x%)|=^x5o~WSP|4mcp(^8u+B0C58mlW zMMmzeEZsD{vW)H$dY|#vfwvsx(Gw4|tGiGim)S_T=hV4!!PitB$V4Zw8N{O<(Qr&H z_09gZ+KP7M7yh;u8AOA>xXEJ*>9HN#l?^sK9=Q2%Sz{IDEIgLnvjU%dBfz$xW;M8$ z!K56?RV$MegSj%BGubt$WQj6R_;fe}C3z(xu!hw2G;TX1EAbky12x^J9VTD>&GqO6M{tpRv?$2>=U;Wzo+4v|^jpP| zW92%JlY4hY8apNhdKJ57*su+(pdzm-`(l0%mnpY+;|cbCRuLtRFxYc93TKyB!B z%GA;H)&yHbi|dUo!H%m$Jr7AAc~hB3yi)Uln|g3*35>1{cB3CR-qFV-5k>Q7yJQ8a z10p+88XX#z6(cK0J#(Fp7fQLOeCXZpE1NHQX=WmG5qAQbhC-vb%=8e(=j62_*8C)I zfuzgFr}EV_orjHl!>+l3VRW1l1!RX%W9r@b#y6c&EwP?b6^8OxET<{X)C`$U%G3r| zn#NPj)5$1Po#BBiF>qI3Tz0Gny$Cmza0_)LRJPzt(gZbc>SXL1&jB9UL72r8unpE2 z4e5--O;2If2|vq`|;(gU&_kiGzXpsRN4!dzv>l znQr+Qz(+(LUgZW*_v{a4ikHsKvd%z-SO+4??x4t31l62Rb4TK5HyYs|5_>~{HQAsZz z{7n|yOvPvz;E|4b8@r0oAdLYx}6+e3iv2F-!1>E9? zS%tIzShDs{w-c>Da?XH%SbkL z!V#??jjHh6TIt9j^&K;7x^W&l73Sx5B(i0m0{ zB;J&{&N(}IO+#M2vSe0j^2wl`oE3w3e)UtrX5PdD5jxjhIJZ`w_wonIH+{+9EMI)# zzpl%?U|yPP!YY;C6#zCkNwsJ>u}jaC>vME{b^LB_0;hJ@96?8hqJpFdZSvFk)9^_P zQEm3CRF$_pH9SMDwFsFo%Yh#Su6#)~iHIwpcKDT6KHw3R&J2&b)a7cY$SaPm1S(GQ z6N2y?)Lg}@u<(&bV=?=Y!52jCIMGGs-G zJY`d$up}5tFJx^(6Ts8CC_8+jItBuE&_nq+!brWfBd$ySu4>u8Ci5{rWx$pk0i^fl zu3T;k#NIY|LniI0>F{%ttScB*XX4~PX>K~A*HyI;rKbfFF>~or+!v^O8~a~e_I%{6 zye@o#w=53{Y%+}!v4fV5TbzFLqtmZ5PBinsPH97vHq^)RzCCc3da=UK*9YA=xS#tf z1oClXX)hPE1-3n5k#@)J z{s5q=H@UBhj^3I+10l|PcNL~$quhY;@t?L}0_+6Cy|x_|=*~zzW}IRbv6_BuAHa$s z!&;^q7qfvamip`SeMSL!t%WG;FgwMa+{)BnGj7QuQ_WJOs?Rn@5`t4BxX-u|R;#=s z;~GsGCym-LX=s8Gfs0FsW}%s7B?7PG$|igojSTDpTMC4#Pkz-A#<;gQ7P!yEtY~#6 zPUbsdN1t=I(esOgFL=fCIni&mtncNyu`WVY@1?Iu#ajtWD|?!XdGx}p-R{BlLFH1A z6j>@_IZ=f-(5T++B`I1a0m|vAm0KOJC$RJo3c#AaYIKmCoQmIhm2e_af zK$1r5ASYQE;>0tu|Mbeg5i~q!)tz7U8>DIC#dY&p2VB}vwLo=SSNWJFr|jwgEOHo^ z6e~_o2@p<8FkY_4RLn%>LTr>((=op4QdH^Gw>%gGxG9h4&r5Dz!+EBDte`6+&}VR= zN7o(~_OcVsnR+io-`95)gk-B4eJtc&1mwXEViDQ{oxiWFItcEM3odX%rh|ozbw2Xd zMe~gZ8manSftr_;ENPo${CKRJ(YtglkI|kaS@x*3iEfv?X1w=EIq;#M<+b5W=0d)g z!{9?3uo9Vog4i}np2WD+vT+Jo_c8Ei5U_Xz zBHwRN&sbo9m7$VXJmH4@4T1se_<{*kJCb;3C(hV~lPEAM{iyFq#pA1P6hmvLkvi8~c?=e>%hAzV<&&Ti0w zD7tJM3rsswSo3Q^bT{fAS{~DA5p9eVedd{S1M+NV(hzjq>^G1lI0uFG&9iEhH(#Uj>(xfa>1(HtXQp;BobuBmjGSFXb zyV}7xJ#7fyNvh*P)ns?jw?yZ9`lKWMPcHY}e_!R4!~s1+m!15~WcN~c7V}IW+3Bpe z?!LWjJ@Pn{3Oa7i+|U}f+#BM+8{Ievb4QCXBQq#Nj~;sE(bx`%>+7-BgPLDO%^)Fp zm815mF1t-r7O0?Zl&ym@Y2w17>!+!d2qDhampE+cV!5|0zUv(vpmYb%?Rjg(l?m&N zGjs<~^6+PJ_DB-=-~?8&Fk(D z00tw(=%}1g%?|ph>Z=N^nEFSq6VHHyVVs4jed|Uzija=57xpN9y`pA@h{45Zl#*rs zZ0vJ$ABL8ls@U{`J8!fg+a~xq7*Cpc4ka&e`(Q=J#@ESCNUUBR>MPDQlgNIF5V;nSI!p0W&Vh-g@dsSSY*Z_Q*K z45=IWkbcO(R}>oQyjQJ1{KI_5i>K|Ws=xZumw@xB7F-w+EGL>?Cpr-%fZt z!NaDeKYbm^)a4L&?5~vyVAVuec^T}l$G|Ie(LUIg1(q9`=p0>Y!!H;AVyBde9a-HR zh#}NMB(9Z!@fhrYQwtYrI#p$`(9$lEwpqcLoM$`vT&5HH@FT~{AN`_Nl@~tzLi(R- zUy?l|haGQmp8w{pe4OVZ%ln*A=&P-sY}gMva$kUQEQ!m^+HOAs?#R!omv*&bJpk@% zANh8|z|jSC%Jjp~onx?&C3W((kvAHw&pLQoXH)=qekg3q!<3?eXf{~UNA*ozRg+?P zqT&*KFCMz9Y<=%nlzpG|Kb5uTe^yz4_!VX02uBt3C8Y(0@pV5dy}ePC&fPX7>2ue? zD;sEqr4t9=M;h7b2&^|?dE}u4IE&jy1PnqppCoS{H++y5mbV8MIbbOD*DOb1E{#mm zn2Bkj1p5Z{WcmXNapo~L2r#H2tbV-$#n-~Ri%xss2DtD306--~$rgyEZb>#ZN2^tf zg9_tO?N!mitd#ql5VDK%mG$L#~+2p;{ zEcKr!!o4}zaQaJWWG2kS=}R-q7bcF5bZxVeO_3eZ`uG3=v_(vl3d=7D0F<>k4aw@K zleGHCfcoor5nKc?M8ZjvlLu>{RVMSL&I!^$(nK_dGNR##^19G~OvVi1)P80bR5o`H zyHttDa%kxiFpuIZ}skjc*wupaz>uL@uCNPSQDo<4y;( z!0u~yJqB*$WO3N|=1`$A&zeFKsWaFivL@6LOyePw?rPE_oKalInZ1uu#{OBnad;=Z zo#4g+>B-ZCRN~PmY#wMwa-UJ?Df&u^kya6K6Wi^q2SX zor+rymqm^v-nuY31~VNq?S(qoSgwy9IP@PWut9AX`Ft%mQcx+^faRlD)YH78NZiRs zpD1_S!$*Oja?p}I`AEaOkboV29I`mlu^sf|MA~>Xgfd!{%3Xb^`5`*QRYu=P*yAMN zmQO9^m%gJc{?bpEFme<7-JI$jFwIW zb;--ou7eQYZIuCbzd(bvz?o(iMwJqy0wtutCcdNyQoU!yFAZUh)MftALu~${3gy#p zM=j6xb8@Br(s@fSPkCepn&u5&wIQgwl852Sz!{Tiky4ejR}k1Z+m4LD7R_rKmnJ(L zuEd=^;m{p6SJL@+hUCH1;ucNM#{l@(nSuBiz~xRGM&E<>V<(I4d+Rph>+F*DLq?P` zN-^*H%%?Ipxd{r=MaMngggpq!4kQgHcf;yCo43>lt%+R3QO)6vK}5eOH>|so!+%JM z(2Q&1%s_9P;8?z${8Q34rA9-O2=x@*qqB(vD4a5LbIrPU>_a_oc$~AxJ{t`Q>c^p5 z{juZfms^(cDcf-7VhLn$AX^9M5c$r$kE7Pt`RGqiPz;e7*zb;o8D4ZSrR{RkOPPOE<#&fNPkOOT4&5(9pjJPlBRl!;#&GK zTV*z#R^BZtx~%Og^y_EK(ruq^Whskq|J737{vXQ90S5P9@_&@gPxu4n;$08Z88cAu zO(0e2YeNwr$=Au0Dowd^uVUc=Pk$T&ba;c=&JFU)Qam5qo+B;JV{xBA1_OQ~k@h)x zu+5UrLe_IbdENa1fVH)|SQ&wd_FBvsP}Q$-=&L`j z4%tGlfeIZt$wd*~I+VKfMFi;KF0F;GJQ|s}bkZ>tm-(Ib^B#XXBn`tKDAqqwV>kgB z047uWOZoBdt0}n~_Vpg8%zO)Tf$!TdKKcG~=+}R;oa1@-0*8P!fgq|*{<4_328iwy zc9Q;p(@-K?hO;(u)w#3RPAUhPV(dBY*HJ%kN9-9^*@3|WNbNvvXkn1S2ATGo3`rgw zD~78HS&ns(K&`V;HAbCA*Mnf!*kh6i>INt~iQL#ZZ)UcfnOok=JcrZ)+hiHhrCbM3 z{?u1G6=Y9`UDZn_jL^YXmt~xIxIhcz`dtOii(6PNYkZ7IJ=^)ax~YGena)MZcf}4x z8Jo$)G`JP8PJ0ts98XuVFLq=3QWvK&5;~d1gL{H|mVLJ1ga~^+zx4y*(fastX$&dBa zN8uMY&zFs})>%40>b~DpSmuLU2X5gYE;b9w)0HzaKc9ze1v1-}Hbf zlT}$UJ#DOt+Cc`A5UA$#zNb?~odD=Xjf$MEeUUPioKh&h1kLR{F%)VQ72Fm_Uw1N= zIyiQfPUW-6%AlTr6??V{bbo@2i$if;Imac$PXz}TzeNdR@2=;r{JSFj?|soA!)bgc zbvJqa_6e zTnEj{9_{gLN1nAcX(gcEXYTs^qo*}ayk7Jvmj>ygEFbZjJA29bwbfDE<1GDH9)2p{ zOJY3hDfFWk%~739$YXwIq$v+GDuJAjVc`OZm>7Y4_TDp^v%pAqOLQ{+H!OM4$}mEd z-?zr{%Sx<`3za%qkxTmTCWnbDJfNcdN1*f%dEj_=G|=@JYq-uXz`%qe`)HPZ@BCysKuUY!8-#|F(EL}F#@+wf2VG?Tf8aInKUR541T{DaK z$c6Tc3&84aF%FXj8QaoO2b86WUuzXySzT6{Z~2(E zE#xX(^_{kMgyhAq>OGIS=@<8~Vi%LGKJ`552oco|aKN^vR@<<0v#n`(jC^ZsP|aX# z*xcqsURPtsm*s>h*=a@W*C*xAKlSroa~flV>+O08ngUqF346#0Wj)Vx7AjysJG(rwKinzSnx#3 z)(}_BgHT-9%2GSKdnuj|?itlp-6gyu;xGM$&H-aAdGNnlX2Z*tdGcazg&f0m+Hl@7 zagxF99!F)9Q8Byncgi+gJxb1ERoRqCVGhCA}uD ziqaGg=ZJZuEgJ6lIA0)Iw}+Oi~c0`CiOew=oj4@W^HN& zH3s=nOGkF{FD%Zp4Ru>>+N_E8@lXBCCQTl16=h}4AgG&TU7}eYI-kTKoMam)f5$ztD#EpKjYWLp)v7u1pn2W4hJ1 z0J@a_d`{y1Hn|M@^?{*QZK<`u!dME&_840b{w-VU@NDEyD;Hs!_58_=v>~^fo+mQu~-4y0^>zAyuHTBKbr++^y0*;;Wje+!oq$o~YLwCdjKV;8u zfMfV%+JP&!S!Z6gWu_j1FoM?6oqR+v?cWnGld;-``RpeYq>0i?%R z{!L%Aj^Y`XKW(<9$IYd#f1Ad|#Iz}C(6K?c(aS7o?A-$dQkDbQ}b&89RgZAa~ zUBdwMgq6Sd1gbpr&0ipH5zO%q(RdLZ6vrmfkGME>7%OkbuZk3PzVDq8=GOXTs@DlW z3AKn&$CFH=A@3x;Bf{4}_JKe?QUq2!zh#V9FIQ01N?&D)ASk>OF(O1JZ{rf{T(jEJ zi!Zj$RWCCo$*lSiON-#Qv^XKiFqlg%OzG^^mKj{X*}2w2U~ zW{C-vrjzXiAtovLXyu>~6?h{62P3Xb55onChDH0~t2c-7`^n3@L+97kQS@u39*7a_sLjI5C zlHf9GOCH{KfR?uYweA}kaoQyQ1#X8zLtYOO*Tf1h1J@foByXNw1NV(Q3 z^T%6xO_{Z`)!6}#)7%zL(^1Om@d z3(PU+?WiNtt|a2qGEO#3KERSAU;-u|Wx1Chu*|YoEV*T|rOU^GL71(QHnyVpSbd=D z3}ha>$l4zqY$d}lwT^|Kvdq|t)`6ZtqJX+ew?~x`%=P5cd7h{eF1Vy!jsQd#G%7+j zb-ybO-u(Bu>v&u^UJD2%5%SQh@Sd1HKK;l0Szl3x9>Ay4L{3FVk=>^oPec*k1&?

r;Jp@x1CG#N$PPfEK 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≻-4mMi; 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 From 6e4e564e40ee1590b7a9f3b4473a7da9b40a9113 Mon Sep 17 00:00:00 2001 From: Jean-Pierre Busch Date: Tue, 30 May 2023 17:02:46 +0200 Subject: [PATCH 078/159] store runner arch in GITHUB_OUTPUT --- action.yml | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) diff --git a/action.yml b/action.yml index 0560e63..3799a27 100644 --- a/action.yml +++ b/action.yml @@ -65,12 +65,13 @@ runs: ref: feature/github-action # TODO: desired behavior? path: ${{ inputs.build-context }}/docker/docker-ros - - name: test runner arch - run: echo "DPKG = $(dpkg --print-architecture) ; runner.arch = ${{ runner.arch }}" + - name: Get runner architecture + id: get-runner-arch + run: echo "RUNNER_ARCH = $(dpkg --print-architecture)" >> $GITHUB_OUTPUT shell: bash - name: Set up QEMU for architecture emulation - if: ${{ !contains(inputs.platform, runner.arch) }} + if: ${{ !contains(inputs.platform, steps.get-runner-arch.outputs.RUNNER_ARCH) }} uses: docker/setup-qemu-action@v2 - name: Set up Docker buildx From 2a4babe2ab889278493a5105a744b14dc017f07a Mon Sep 17 00:00:00 2001 From: Jean-Pierre Busch Date: Tue, 30 May 2023 17:03:26 +0200 Subject: [PATCH 079/159] test print --- action.yml | 2 ++ 1 file changed, 2 insertions(+) diff --git a/action.yml b/action.yml index 3799a27..3933e2b 100644 --- a/action.yml +++ b/action.yml @@ -57,6 +57,8 @@ runs: - name: Checkout repository uses: actions/checkout@v3 + - name: test prints + run: echo "GITHUB_WORKSPACE = ${{ github.workspace }} ; " && pwd && ls -al .. - name: Checkout docker-ros uses: actions/checkout@v3 From 5e9af458815d8d8cf6a9db10f182d13d3d96bcc6 Mon Sep 17 00:00:00 2001 From: Jean-Pierre Busch Date: Tue, 30 May 2023 17:05:05 +0200 Subject: [PATCH 080/159] test print --- action.yml | 2 ++ 1 file changed, 2 insertions(+) diff --git a/action.yml b/action.yml index 3933e2b..e2afde5 100644 --- a/action.yml +++ b/action.yml @@ -57,8 +57,10 @@ runs: - name: Checkout repository uses: actions/checkout@v3 + - name: test prints run: echo "GITHUB_WORKSPACE = ${{ github.workspace }} ; " && pwd && ls -al .. + shell: bash - name: Checkout docker-ros uses: actions/checkout@v3 From a92fc59584d263b25e9601b4feb07b4342fae6d7 Mon Sep 17 00:00:00 2001 From: Jean-Pierre Busch Date: Tue, 30 May 2023 17:16:05 +0200 Subject: [PATCH 081/159] test print --- action.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/action.yml b/action.yml index e2afde5..a294e86 100644 --- a/action.yml +++ b/action.yml @@ -59,7 +59,7 @@ runs: uses: actions/checkout@v3 - name: test prints - run: echo "GITHUB_WORKSPACE = ${{ github.workspace }} ; " && pwd && ls -al .. + run: echo "GITHUB_WORKSPACE = ${{ github.workspace }} ; " && pwd && ls -al ../.. && find / -name "docker-ros" shell: bash - name: Checkout docker-ros From d9067782ba12a3e8711fd61b54dcd63675e39517 Mon Sep 17 00:00:00 2001 From: Jean-Pierre Busch Date: Tue, 30 May 2023 17:39:41 +0200 Subject: [PATCH 082/159] cp docker-ros instead auf checkout again --- action.yml | 22 +++++++++++++++------- 1 file changed, 15 insertions(+), 7 deletions(-) diff --git a/action.yml b/action.yml index a294e86..bde5e66 100644 --- a/action.yml +++ b/action.yml @@ -59,15 +59,23 @@ runs: uses: actions/checkout@v3 - name: test prints - run: echo "GITHUB_WORKSPACE = ${{ github.workspace }} ; " && pwd && ls -al ../.. && find / -name "docker-ros" + run: echo "GITHUB_WORKSPACE = ${{ github.workspace }} ; " && pwd && ls -al ../../_actions && ls -al ../../_actions/ika-rwth-aachen/docker-ros shell: bash - - name: Checkout docker-ros - uses: actions/checkout@v3 - with: - repository: ika-rwth-aachen/docker-ros - ref: feature/github-action # TODO: desired behavior? - path: ${{ inputs.build-context }}/docker/docker-ros + - name: Copy docker-ros + working-directory: ${{ inputs.build-context }} + run: | + mkdir -p docker/docker-ros + cp /home/runner/work/_actions/ika-rwth-aachen/docker-ros docker/docker-ros + ls -al docker/docker-ros + shell: bash + + #- name: Checkout docker-ros # TODO: only if not included as submodule + # uses: actions/checkout@v3 + # with: + # repository: ika-rwth-aachen/docker-ros + # ref: feature/github-action # TODO: selbe ref wie action.yml; find and cp or clone with ref + # path: ${{ inputs.build-context }}/docker/docker-ros # TODO: reative to github.workspace? - name: Get runner architecture id: get-runner-arch From 982a15ae14cfcac0044956c40f54fa1e6415cde5 Mon Sep 17 00:00:00 2001 From: Jean-Pierre Busch Date: Tue, 30 May 2023 17:57:29 +0200 Subject: [PATCH 083/159] test print --- action.yml | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/action.yml b/action.yml index bde5e66..2cc76a7 100644 --- a/action.yml +++ b/action.yml @@ -59,14 +59,14 @@ runs: uses: actions/checkout@v3 - name: test prints - run: echo "GITHUB_WORKSPACE = ${{ github.workspace }} ; " && pwd && ls -al ../../_actions && ls -al ../../_actions/ika-rwth-aachen/docker-ros + run: ls -al ../../_actions && ls -al ../../_actions/ika-rwth-aachen/docker-ros && ls -al ../../_actions/ika-rwth-aachen/docker-ros/feature && ls -al ../../_actions/ika-rwth-aachen/docker-ros/feature/github-action shell: bash - name: Copy docker-ros working-directory: ${{ inputs.build-context }} run: | mkdir -p docker/docker-ros - cp /home/runner/work/_actions/ika-rwth-aachen/docker-ros docker/docker-ros + cp -r /home/runner/work/_actions/ika-rwth-aachen/docker-ros/feature/github-action docker/docker-ros ls -al docker/docker-ros shell: bash From 719921d2e8f2e00df1df00ccfa73ced123e3e6dd Mon Sep 17 00:00:00 2001 From: Jean-Pierre Busch Date: Tue, 30 May 2023 18:07:21 +0200 Subject: [PATCH 084/159] test print --- action.yml | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/action.yml b/action.yml index 2cc76a7..8173e7e 100644 --- a/action.yml +++ b/action.yml @@ -66,7 +66,11 @@ runs: working-directory: ${{ inputs.build-context }} run: | mkdir -p docker/docker-ros - cp -r /home/runner/work/_actions/ika-rwth-aachen/docker-ros/feature/github-action docker/docker-ros + cp -r /home/runner/work/_actions/ika-rwth-aachen/docker-ros/feature/github-action/* docker/docker-ros + cd /home/runner/work/_actions/ika-rwth-aachen/docker-ros + git status + git rev-parse --abbrev-ref HEAD + cd - ls -al docker/docker-ros shell: bash From edd7467183eca758180370e77ddf54091f00407f Mon Sep 17 00:00:00 2001 From: Jean-Pierre Busch Date: Tue, 30 May 2023 18:23:10 +0200 Subject: [PATCH 085/159] use checkout action for docker-ros and add ref as input --- action.yml | 34 +++++++++++----------------------- 1 file changed, 11 insertions(+), 23 deletions(-) diff --git a/action.yml b/action.yml index 8173e7e..a05f97e 100644 --- a/action.yml +++ b/action.yml @@ -3,9 +3,13 @@ description: "docker-ros automatically builds development and deployment Docker inputs: + docker-ros-ref: + description: "Ref of docker-ros" + default: main + target: description: "Target stage of Dockerfile (comma-separated list) [dev|run]" - default: "run" + default: run platform: description: "Target platform architecture (comma-separated list) [amd64|arm64|...]" @@ -58,28 +62,12 @@ runs: - name: Checkout repository uses: actions/checkout@v3 - - name: test prints - run: ls -al ../../_actions && ls -al ../../_actions/ika-rwth-aachen/docker-ros && ls -al ../../_actions/ika-rwth-aachen/docker-ros/feature && ls -al ../../_actions/ika-rwth-aachen/docker-ros/feature/github-action - shell: bash - - - name: Copy docker-ros - working-directory: ${{ inputs.build-context }} - run: | - mkdir -p docker/docker-ros - cp -r /home/runner/work/_actions/ika-rwth-aachen/docker-ros/feature/github-action/* docker/docker-ros - cd /home/runner/work/_actions/ika-rwth-aachen/docker-ros - git status - git rev-parse --abbrev-ref HEAD - cd - - ls -al docker/docker-ros - shell: bash - - #- name: Checkout docker-ros # TODO: only if not included as submodule - # uses: actions/checkout@v3 - # with: - # repository: ika-rwth-aachen/docker-ros - # ref: feature/github-action # TODO: selbe ref wie action.yml; find and cp or clone with ref - # path: ${{ inputs.build-context }}/docker/docker-ros # TODO: reative to github.workspace? + - name: Checkout docker-ros # TODO: only if not included as submodule + uses: actions/checkout@v3 + with: + repository: ika-rwth-aachen/docker-ros + ref: ${{ inputs.docker-ros-ref }} # TODO: could be identified by the action ref + path: ${{ inputs.build-context }}/docker/docker-ros # TODO: reative to github.workspace? - name: Get runner architecture id: get-runner-arch From 164b8e4f00ceb9a592e59c61765f510ab906fdb0 Mon Sep 17 00:00:00 2001 From: Jean-Pierre Busch Date: Tue, 30 May 2023 19:37:03 +0200 Subject: [PATCH 086/159] add prefix to internal envs --- action.yml | 6 +++--- scripts/build.sh | 4 ++-- scripts/ci.sh | 16 ++++++++-------- 3 files changed, 13 insertions(+), 13 deletions(-) diff --git a/action.yml b/action.yml index a05f97e..9179589 100644 --- a/action.yml +++ b/action.yml @@ -127,6 +127,6 @@ runs: COMMAND: ${{ inputs.command }} IMAGE: ${{ inputs.image }} DEV_IMAGE: ${{ inputs.dev-image }} - ENABLE_IMAGE_PUSH: true - ENABLE_MULTIARCH_BUILD: true - IMAGE_POSTFIX: ${{ github.ref != format('refs/heads/{0}', github.event.repository.default_branch) && format('_{0}_ci', steps.slugify-ref-name.outputs.slug) || '' }} + _ENABLE_IMAGE_PUSH: true + _ENABLE_MULTIARCH_BUILD: true + _IMAGE_POSTFIX: ${{ github.ref != format('refs/heads/{0}', github.event.repository.default_branch) && format('_{0}_ci', steps.slugify-ref-name.outputs.slug) || '' }} diff --git a/scripts/build.sh b/scripts/build.sh index b79f5ae..a4eca35 100755 --- a/scripts/build.sh +++ b/scripts/build.sh @@ -14,7 +14,7 @@ build_image() { --target "${TARGET}" \ --platform "${PLATFORM}" \ --tag "${IMAGE}" \ - $(if [[ "${ENABLE_IMAGE_PUSH}" == "true" ]]; then echo "--push"; else echo "--load"; fi) \ + $(if [[ "${_ENABLE_IMAGE_PUSH}" == "true" ]]; then echo "--push"; else echo "--load"; fi) \ --build-arg BASE_IMAGE="${BASE_IMAGE}" \ --build-arg COMMAND="${COMMAND}" \ --build-arg GIT_HTTPS_PASSWORD="${GIT_HTTPS_PASSWORD}" \ @@ -33,6 +33,6 @@ if [[ "${BASH_SOURCE[0]}" == "${0}" ]]; then require_var "BASE_IMAGE" require_var "IMAGE" [[ "${TARGET}" == *"run"* ]] && require_var "COMMAND" - ENABLE_IMAGE_PUSH="${ENABLE_IMAGE_PUSH:-false}" + _ENABLE_IMAGE_PUSH="${_ENABLE_IMAGE_PUSH:-false}" build_image fi diff --git a/scripts/ci.sh b/scripts/ci.sh index 1c40437..9b054cc 100755 --- a/scripts/ci.sh +++ b/scripts/ci.sh @@ -14,21 +14,21 @@ require_var "BASE_IMAGE" require_var "IMAGE" [[ "${TARGET}" == *"run"* ]] && require_var "COMMAND" DEV_IMAGE="${DEV_IMAGE:-${IMAGE}-dev}" # TODO: what if IMAGE has no TAG? -ENABLE_IMAGE_PUSH="${ENABLE_IMAGE_PUSH:-false}" -ENABLE_MULTIARCH_BUILD="${ENABLE_MULTIARCH_BUILD:-false}" -IMAGE_POSTFIX="${IMAGE_POSTFIX:-""}" +_ENABLE_IMAGE_PUSH="${_ENABLE_IMAGE_PUSH:-false}" +_ENABLE_MULTIARCH_BUILD="${_ENABLE_MULTIARCH_BUILD:-false}" +_IMAGE_POSTFIX="${_IMAGE_POSTFIX:-""}" # write image name for industrial_ci to output # TODO: GitHub-only industrial_ci_image="${IMAGE}" [[ "${TARGET}" == *"dev"* ]] && industrial_ci_image="${DEV_IMAGE}" -[[ -n "${IMAGE_POSTFIX}" ]] && industrial_ci_image="${industrial_ci_image}${IMAGE_POSTFIX}" -[[ "${ENABLE_MULTIARCH_BUILD}" != "true" ]] && industrial_ci_image="${industrial_ci_image}-$(dpkg --print-architecture)" +[[ -n "${_IMAGE_POSTFIX}" ]] && industrial_ci_image="${industrial_ci_image}${_IMAGE_POSTFIX}" +[[ "${_ENABLE_MULTIARCH_BUILD}" != "true" ]] && industrial_ci_image="${industrial_ci_image}-$(dpkg --print-architecture)" echo "INDUSTRIAL_CI_IMAGE=${industrial_ci_image}" >> "${GITHUB_OUTPUT}" # parse (potentially) comma-separated lists to arrays IFS="," read -ra TARGETS <<< "${TARGET}" -if [[ "${ENABLE_MULTIARCH_BUILD}" == "true" ]]; then +if [[ "${_ENABLE_MULTIARCH_BUILD}" == "true" ]]; then IFS="," read -ra PLATFORMS <<< "${PLATFORM}" else PLATFORMS=( "${PLATFORM}" ) @@ -42,8 +42,8 @@ for PLATFORM in "${PLATFORMS[@]}"; do open_log_group "Build ${TARGET} image (${PLATFORM})" image="${IMAGE}" [[ "${TARGET}" == "dev" ]] && image="${DEV_IMAGE}" - [[ -n "${IMAGE_POSTFIX}" ]] && image="${image}${IMAGE_POSTFIX}" - [[ "${ENABLE_MULTIARCH_BUILD}" != "true" ]] && image="${image}-${PLATFORM}" + [[ -n "${_IMAGE_POSTFIX}" ]] && image="${image}${_IMAGE_POSTFIX}" + [[ "${_ENABLE_MULTIARCH_BUILD}" != "true" ]] && image="${image}-${PLATFORM}" IMAGE="${image}" build_image close_log_group done From 49daaa296faf33bd19d1f9604471f32985a470e0 Mon Sep 17 00:00:00 2001 From: Jean-Pierre Busch Date: Wed, 31 May 2023 00:00:56 +0200 Subject: [PATCH 087/159] test architecture for strategy --- .github/workflows/main.yml | 13 +++++++++++-- action.yml | 4 +++- 2 files changed, 14 insertions(+), 3 deletions(-) diff --git a/.github/workflows/main.yml b/.github/workflows/main.yml index 9157f58..218ddf9 100644 --- a/.github/workflows/main.yml +++ b/.github/workflows/main.yml @@ -5,12 +5,21 @@ jobs: name: Trigger docker-ros-ci workflow runs-on: ubuntu-latest steps: - - name: Trigger Workflow and Wait + - name: Trigger docker-ros-ci strategy uses: convictional/trigger-workflow-and-wait@v1.6.5 with: owner: ika-rwth-aachen repo: docker-ros-ci - ref: feature/github-workflow + ref: feature/github-workflow # TODO: set to main + workflow_file_name: strategy.yml + github_token: ${{ secrets.PAT }} # Personal Access Token with appropriate permissions + client_payload: '{"docker-ros-git-ref": "${{ github.ref_name }}"}' + - name: Trigger docker-ros-ci + uses: convictional/trigger-workflow-and-wait@v1.6.5 + with: + owner: ika-rwth-aachen + repo: docker-ros-ci + ref: feature/github-workflow # TODO: set to main workflow_file_name: main.yml github_token: ${{ secrets.PAT }} # Personal Access Token with appropriate permissions client_payload: '{"docker-ros-git-ref": "${{ github.ref_name }}"}' \ No newline at end of file diff --git a/action.yml b/action.yml index 9179589..df1f3df 100644 --- a/action.yml +++ b/action.yml @@ -71,7 +71,9 @@ runs: - name: Get runner architecture id: get-runner-arch - run: echo "RUNNER_ARCH = $(dpkg --print-architecture)" >> $GITHUB_OUTPUT + run: | + echo "$(dpkg --print-architecture)" + echo "RUNNER_ARCH=$(dpkg --print-architecture)" >> $GITHUB_OUTPUT shell: bash - name: Set up QEMU for architecture emulation From 8558e0cc9b4b06fff0d715d9fbf530f32189cd87 Mon Sep 17 00:00:00 2001 From: Jean-Pierre Busch Date: Wed, 31 May 2023 12:05:45 +0200 Subject: [PATCH 088/159] change postfix of industrial_ci_image --- scripts/ci.sh | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/scripts/ci.sh b/scripts/ci.sh index 9b054cc..6dbb59b 100755 --- a/scripts/ci.sh +++ b/scripts/ci.sh @@ -23,7 +23,11 @@ _IMAGE_POSTFIX="${_IMAGE_POSTFIX:-""}" industrial_ci_image="${IMAGE}" [[ "${TARGET}" == *"dev"* ]] && industrial_ci_image="${DEV_IMAGE}" [[ -n "${_IMAGE_POSTFIX}" ]] && industrial_ci_image="${industrial_ci_image}${_IMAGE_POSTFIX}" -[[ "${_ENABLE_MULTIARCH_BUILD}" != "true" ]] && industrial_ci_image="${industrial_ci_image}-$(dpkg --print-architecture)" +if [[ "${PLATFORM}" != *","* ]]; then + industrial_ci_image="${industrial_ci_image}-${PLATFORM}" +elif [[ "${_ENABLE_MULTIARCH_BUILD}" != "true" ]]; then + industrial_ci_image="${industrial_ci_image}-$(dpkg --print-architecture)" +fi echo "INDUSTRIAL_CI_IMAGE=${industrial_ci_image}" >> "${GITHUB_OUTPUT}" # parse (potentially) comma-separated lists to arrays From 77efdbfe61c5c247d7e4b2bf96be15090008ce9f Mon Sep 17 00:00:00 2001 From: Lennart Reiher Date: Wed, 31 May 2023 16:57:53 +0200 Subject: [PATCH 089/159] add citation --- CITATION.cff | 30 ++++++++++++++++++++++++++++++ 1 file changed, 30 insertions(+) create mode 100644 CITATION.cff diff --git a/CITATION.cff b/CITATION.cff new file mode 100644 index 0000000..97a4c19 --- /dev/null +++ b/CITATION.cff @@ -0,0 +1,30 @@ +cff-version: 1.2.0 +message: "We hope that our tools can help your research. If this is the case, please cite it using the following metadata." + +title: dorotos +type: software +repository-code: "https://github.com/ika-rwth-aachen/docker-ros" +date-released: 2023-05-28 +authors: + - given-names: Jean-Pierre + family-names: Busch + - given-names: Lennart + family-names: Reiher + +preferred-citation: + title: "Enabling the Deployment of Any-Scale Robotic Applications in Microservice-Based Service-Oriented Architectures through Automated Containerization" + type: misc + # conference: + # name: + # month: + year: 2023 + # doi: "" + authors: + - given-names: Jean-Pierre + family-names: Busch + orcid: "https://orcid.org/0009-0000-1417-0463" + - given-names: Lennart + family-names: Reiher + orcid: "https://orcid.org/0000-0002-7309-164X" + - given-names: Lutz + family-names: Eckstein From bcfa6d52e8c2037f8c75989dedcf394ce0bcc60e Mon Sep 17 00:00:00 2001 From: Jean-Pierre Busch Date: Wed, 31 May 2023 17:53:45 +0200 Subject: [PATCH 090/159] trigger ros1 and ros2 run in docker-ros-ci --- .github/workflows/main.yml | 8 ++++---- action.yml | 3 +++ 2 files changed, 7 insertions(+), 4 deletions(-) diff --git a/.github/workflows/main.yml b/.github/workflows/main.yml index 218ddf9..d77f661 100644 --- a/.github/workflows/main.yml +++ b/.github/workflows/main.yml @@ -5,21 +5,21 @@ jobs: name: Trigger docker-ros-ci workflow runs-on: ubuntu-latest steps: - - name: Trigger docker-ros-ci strategy + - name: Trigger docker-ros-ci ros1 uses: convictional/trigger-workflow-and-wait@v1.6.5 with: owner: ika-rwth-aachen repo: docker-ros-ci ref: feature/github-workflow # TODO: set to main - workflow_file_name: strategy.yml + workflow_file_name: main-ros1.yml github_token: ${{ secrets.PAT }} # Personal Access Token with appropriate permissions client_payload: '{"docker-ros-git-ref": "${{ github.ref_name }}"}' - - name: Trigger docker-ros-ci + - name: Trigger docker-ros-ci ros2 uses: convictional/trigger-workflow-and-wait@v1.6.5 with: owner: ika-rwth-aachen repo: docker-ros-ci ref: feature/github-workflow # TODO: set to main - workflow_file_name: main.yml + workflow_file_name: main-ros2.yml github_token: ${{ secrets.PAT }} # Personal Access Token with appropriate permissions client_payload: '{"docker-ros-git-ref": "${{ github.ref_name }}"}' \ No newline at end of file diff --git a/action.yml b/action.yml index df1f3df..b31665c 100644 --- a/action.yml +++ b/action.yml @@ -73,6 +73,9 @@ runs: id: get-runner-arch run: | echo "$(dpkg --print-architecture)" + echo "${GITHUB_ACTION}" + echo "${GITHUB_ACTION_PATH}" + echo "${GITHUB_ACTION_REPOSITORY}" echo "RUNNER_ARCH=$(dpkg --print-architecture)" >> $GITHUB_OUTPUT shell: bash From 76cde6746b63b224e1ae05261d7be54392f786e8 Mon Sep 17 00:00:00 2001 From: Jean-Pierre Busch Date: Wed, 31 May 2023 17:59:21 +0200 Subject: [PATCH 091/159] trigger in seperate jobs --- .github/workflows/main.yml | 10 +++++++--- 1 file changed, 7 insertions(+), 3 deletions(-) diff --git a/.github/workflows/main.yml b/.github/workflows/main.yml index d77f661..8e13a6a 100644 --- a/.github/workflows/main.yml +++ b/.github/workflows/main.yml @@ -1,11 +1,11 @@ on: [push] jobs: - trigger_workflow: - name: Trigger docker-ros-ci workflow + trigger-docker-ros-ci-ros1: + name: Trigger docker-ros-ci ros1 workflow runs-on: ubuntu-latest steps: - - name: Trigger docker-ros-ci ros1 + - name: Trigger docker-ros-ci ros1 workflow uses: convictional/trigger-workflow-and-wait@v1.6.5 with: owner: ika-rwth-aachen @@ -14,6 +14,10 @@ jobs: workflow_file_name: main-ros1.yml github_token: ${{ secrets.PAT }} # Personal Access Token with appropriate permissions client_payload: '{"docker-ros-git-ref": "${{ github.ref_name }}"}' + trigger-docker-ros-ci-ros2: + name: Trigger docker-ros-ci ros2 workflow + runs-on: ubuntu-latest + steps: - name: Trigger docker-ros-ci ros2 uses: convictional/trigger-workflow-and-wait@v1.6.5 with: From 015eb76fc956d8ae460c20e24edcb702973b5cfd Mon Sep 17 00:00:00 2001 From: Jean-Pierre Busch Date: Wed, 31 May 2023 23:50:45 +0200 Subject: [PATCH 092/159] copy docker-ros instead of checkout --- action.yml | 20 +++++++++++++------- 1 file changed, 13 insertions(+), 7 deletions(-) diff --git a/action.yml b/action.yml index b31665c..48c5662 100644 --- a/action.yml +++ b/action.yml @@ -62,12 +62,18 @@ runs: - name: Checkout repository uses: actions/checkout@v3 - - name: Checkout docker-ros # TODO: only if not included as submodule - uses: actions/checkout@v3 - with: - repository: ika-rwth-aachen/docker-ros - ref: ${{ inputs.docker-ros-ref }} # TODO: could be identified by the action ref - path: ${{ inputs.build-context }}/docker/docker-ros # TODO: reative to github.workspace? + #- name: Checkout docker-ros # TODO: only if not included as submodule + # uses: actions/checkout@v3 + # with: + # repository: ika-rwth-aachen/docker-ros + # ref: ${{ inputs.docker-ros-ref }} # TODO: could be identified by the action ref + # path: ${{ inputs.build-context }}/docker/docker-ros # TODO: reative to github.workspace? + + - name: copy docker-ros + working-directory: ${{ inputs.build-context }} + shell: bash + run: | + [ -d "docker/docker-ros" ] || mkdir docker/docker-ros && cp -r ${GITHUB_ACTION_PATH}/* docker/docker-ros - name: Get runner architecture id: get-runner-arch @@ -75,7 +81,7 @@ runs: echo "$(dpkg --print-architecture)" echo "${GITHUB_ACTION}" echo "${GITHUB_ACTION_PATH}" - echo "${GITHUB_ACTION_REPOSITORY}" + ls -al ${GITHUB_ACTION_PATH} echo "RUNNER_ARCH=$(dpkg --print-architecture)" >> $GITHUB_OUTPUT shell: bash From 619777d7a039456d7ac391a942d43e2f11b863dc Mon Sep 17 00:00:00 2001 From: Lennart Reiher Date: Thu, 1 Jun 2023 15:34:42 +0200 Subject: [PATCH 093/159] checkout client repository recursively and with lfs --- action.yml | 3 +++ 1 file changed, 3 insertions(+) diff --git a/action.yml b/action.yml index 48c5662..94b544b 100644 --- a/action.yml +++ b/action.yml @@ -61,6 +61,9 @@ runs: - name: Checkout repository uses: actions/checkout@v3 + with: + submodules: true + lfs: true #- name: Checkout docker-ros # TODO: only if not included as submodule # uses: actions/checkout@v3 From 5ccc027ba6cf4f62c09ea35783ba6bfab34a39f6 Mon Sep 17 00:00:00 2001 From: Lennart Reiher Date: Thu, 1 Jun 2023 15:59:13 +0200 Subject: [PATCH 094/159] clean up action.yml --- action.yml | 60 ++++++++++++++++++++++-------------------------------- 1 file changed, 24 insertions(+), 36 deletions(-) diff --git a/action.yml b/action.yml index 94b544b..cdba282 100644 --- a/action.yml +++ b/action.yml @@ -3,10 +3,6 @@ description: "docker-ros automatically builds development and deployment Docker inputs: - docker-ros-ref: - description: "Ref of docker-ros" - default: main - target: description: "Target stage of Dockerfile (comma-separated list) [dev|run]" default: run @@ -53,59 +49,44 @@ runs: using: "composite" steps: - - name: Slugify ref name - id: slugify-ref-name - uses: gacts/github-slug@v1 - with: - to-slug: ${{ github.ref_name }} - - name: Checkout repository uses: actions/checkout@v3 with: submodules: true lfs: true - #- name: Checkout docker-ros # TODO: only if not included as submodule - # uses: actions/checkout@v3 - # with: - # repository: ika-rwth-aachen/docker-ros - # ref: ${{ inputs.docker-ros-ref }} # TODO: could be identified by the action ref - # path: ${{ inputs.build-context }}/docker/docker-ros # TODO: reative to github.workspace? - - - name: copy docker-ros - working-directory: ${{ inputs.build-context }} + - name: Set up docker-ros shell: bash + working-directory: ${{ inputs.build-context }} run: | - [ -d "docker/docker-ros" ] || mkdir docker/docker-ros && cp -r ${GITHUB_ACTION_PATH}/* docker/docker-ros + if [[ -d "docker/docker-ros" ]]; then + mkdir docker + cp -r ${GITHUB_ACTION_PATH} docker/docker-ros + fi - - name: Get runner architecture - id: get-runner-arch - run: | - echo "$(dpkg --print-architecture)" - echo "${GITHUB_ACTION}" - echo "${GITHUB_ACTION_PATH}" - ls -al ${GITHUB_ACTION_PATH} - echo "RUNNER_ARCH=$(dpkg --print-architecture)" >> $GITHUB_OUTPUT + - name: Prepare setup of QEMU + id: prepare-setup-of-qemu shell: bash + run: echo "RUNNER_ARCH=$(dpkg --print-architecture)" >> $GITHUB_OUTPUT - - name: Set up QEMU for architecture emulation - if: ${{ !contains(inputs.platform, steps.get-runner-arch.outputs.RUNNER_ARCH) }} + - name: Set up QEMU + if: ${{ steps.prepare-setup-of-qemu.outputs.RUNNER_ARCH != inputs.platform }} uses: docker/setup-qemu-action@v2 - - name: Set up Docker buildx - uses: docker/setup-buildx-action@v2 - - name: Login to Docker registry uses: docker/login-action@v2 with: registry: ${{ inputs.registry }} username: ${{ inputs.registry-username }} password: ${{ inputs.registry-password }} + + - name: Set up Docker buildx + uses: docker/setup-buildx-action@v2 - name: Build images id: build-images - working-directory: ${{ inputs.build-context }} shell: bash + working-directory: ${{ inputs.build-context }} run: docker/docker-ros/scripts/ci.sh env: PLATFORM: ${{ inputs.platform }} @@ -116,12 +97,13 @@ runs: DEV_IMAGE: ${{ inputs.dev-image }} - name: Set up industrial_ci + if: ${{ inputs.enable-industrial-ci == 'true' }} shell: bash run: test -f ${{ inputs.build-context }}/.repos || echo "repositories:" > ${{ inputs.build-context }}/.repos - name: Run industrial_ci - uses: ros-industrial/industrial_ci@master if: ${{ inputs.enable-industrial-ci == 'true' }} + uses: ros-industrial/industrial_ci@master env: UPSTREAM_WORKSPACE: ${{ inputs.build-context }}/.repos TARGET_WORKSPACE: ${{ inputs.build-context }} @@ -130,9 +112,15 @@ runs: DOCKER_IMAGE: ${{ steps.build-images.outputs.INDUSTRIAL_CI_IMAGE }} DOCKER_PULL: false + - name: Slugify ref name + id: slugify-ref-name + uses: gacts/github-slug@v1 + with: + to-slug: ${{ github.ref_name }} + - name: Push images - working-directory: ${{ inputs.build-context }} shell: bash + working-directory: ${{ inputs.build-context }} run: docker/docker-ros/scripts/ci.sh env: PLATFORM: ${{ inputs.platform }} From e2b84571087ba81d063da979aef081a09ef2232d Mon Sep 17 00:00:00 2001 From: Lennart Reiher Date: Thu, 1 Jun 2023 17:41:27 +0200 Subject: [PATCH 095/159] add first working integration of git_ssh_key --- docker/Dockerfile | 16 ++++++++++++++-- 1 file changed, 14 insertions(+), 2 deletions(-) diff --git a/docker/Dockerfile b/docker/Dockerfile index 21758f2..17505d7 100644 --- a/docker/Dockerfile +++ b/docker/Dockerfile @@ -47,11 +47,23 @@ RUN shopt -s dotglob && \ rm -r src/repository # clone .repos upstream dependencies +# TODO: remove hard-coded git server +# TODO: pass build-args for git authentication ARG GIT_HTTPS_URL=https://gitlab.ika.rwth-aachen.de ARG GIT_HTTPS_USER= ARG GIT_HTTPS_PASSWORD= -RUN if [ ! -z ${GIT_HTTPS_USER} ]; then \ - git config --global url.https://${GIT_HTTPS_USER}:${GIT_HTTPS_PASSWORD}@gitlab.ika.rwth-aachen.de.insteadOf ${GIT_HTTPS_URL} ; \ +RUN if [ -n ${GIT_HTTPS_USER} ]; then \ + git config --global url.https://${GIT_HTTPS_USER}:${GIT_HTTPS_PASSWORD}@gitlab.ika.rwth-aachen.de.insteadOf ${GIT_HTTPS_URL} && \ + fi +ARG GIT_SSH_PRIVATE_KEY= +ARG GIT_SSH_KNOWN_HOST_KEYS= +RUN if [ -n ${GIT_SSH_PRIVATE_KEY} ]; then \ + echo -e ${GIT_SSH_PRIVATE_KEY} > /tmp/ssh_id && \ + chmod 400 /tmp/ssh_id && \ + git config --global core.sshCommand "ssh -i /.ssh_key" ; \ + mkdir -p ~/.ssh && \ + touch ~/.ssh/known_hosts && \ + echo -e ${GIT_SSH_KNOWN_HOST_KEYS} >> ~/.ssh/known_hosts && \ fi COPY docker/docker-ros/docker/recursive_vcs_import.py /usr/local/bin RUN apt-get update && \ From c9a97c92b30e01025c0d7945493d8fbe56107c17 Mon Sep 17 00:00:00 2001 From: Jean-Pierre Busch Date: Thu, 1 Jun 2023 18:02:51 +0200 Subject: [PATCH 096/159] fix cp docker-ros --- action.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/action.yml b/action.yml index cdba282..3d9917e 100644 --- a/action.yml +++ b/action.yml @@ -59,7 +59,7 @@ runs: shell: bash working-directory: ${{ inputs.build-context }} run: | - if [[ -d "docker/docker-ros" ]]; then + if ! [[ -d "docker/docker-ros" ]]; then mkdir docker cp -r ${GITHUB_ACTION_PATH} docker/docker-ros fi From 56d635b40159216f9722a10994c8799ff2327680 Mon Sep 17 00:00:00 2001 From: Jean-Pierre Busch Date: Thu, 1 Jun 2023 18:33:25 +0200 Subject: [PATCH 097/159] split image name and tag inputs --- action.yml | 29 ++++++++++++++++++++--------- scripts/ci.sh | 9 +++++++-- 2 files changed, 27 insertions(+), 11 deletions(-) diff --git a/action.yml b/action.yml index 3d9917e..a19ff5a 100644 --- a/action.yml +++ b/action.yml @@ -17,12 +17,19 @@ inputs: command: description: "Launch command of run image (required if target=run)" - image: - description: "Image name:tag of run image" - default: ghcr.io/${{ github.repository }}:latest + image-name: + description: "Image name of run image" + default: ghcr.io/${{ github.repository }} - dev-image: - description: "Image name:tag of dev image" + tag: + description: "Image tag of run image" + default: latest + + dev-image-name: + description: "Image name of dev image" + + dev-tag: + description: "Image tag of dev image" build-context: description: "Build context of Docker build process" @@ -93,8 +100,10 @@ runs: TARGET: ${{ inputs.target }} BASE_IMAGE: ${{ inputs.base-image }} COMMAND: ${{ inputs.command }} - IMAGE: ${{ inputs.image }} - DEV_IMAGE: ${{ inputs.dev-image }} + IMAGE_NAME: ${{ inputs.image-name }} + TAG: ${{ inputs.tag }} + DEV_IMAGE_NAME: ${{ inputs.dev-image-name }} + DEV_TAG: ${{ inputs.dev-tag }} - name: Set up industrial_ci if: ${{ inputs.enable-industrial-ci == 'true' }} @@ -127,8 +136,10 @@ runs: TARGET: ${{ inputs.target }} BASE_IMAGE: ${{ inputs.base-image }} COMMAND: ${{ inputs.command }} - IMAGE: ${{ inputs.image }} - DEV_IMAGE: ${{ inputs.dev-image }} + IMAGE_NAME: ${{ inputs.image-name }} + TAG: ${{ inputs.tag }} + DEV_IMAGE_NAME: ${{ inputs.dev-image-name }} + DEV_TAG: ${{ inputs.dev-tag }} _ENABLE_IMAGE_PUSH: true _ENABLE_MULTIARCH_BUILD: true _IMAGE_POSTFIX: ${{ github.ref != format('refs/heads/{0}', github.event.repository.default_branch) && format('_{0}_ci', steps.slugify-ref-name.outputs.slug) || '' }} diff --git a/scripts/ci.sh b/scripts/ci.sh index 6dbb59b..572a03b 100755 --- a/scripts/ci.sh +++ b/scripts/ci.sh @@ -11,9 +11,14 @@ source "${ROOT_PATH}/scripts/utils.sh" TARGET="${TARGET:-run}" PLATFORM="${PLATFORM:-$(dpkg --print-architecture)}" require_var "BASE_IMAGE" -require_var "IMAGE" +require_var "IMAGE_NAME" +TAG="${TAG:-latest}" [[ "${TARGET}" == *"run"* ]] && require_var "COMMAND" -DEV_IMAGE="${DEV_IMAGE:-${IMAGE}-dev}" # TODO: what if IMAGE has no TAG? +DEV_IMAGE_NAME="${DEV_IMAGE_NAME:-${IMAGE_NAME}}" +DEV_TAG="${DEV_TAG:-${TAG}-dev}" + +IMAGE="${IMAGE_NAME}:${TAG}" +DEV_IMAGE="${DEV_IMAGE_NAME}:${DEV_TAG}" _ENABLE_IMAGE_PUSH="${_ENABLE_IMAGE_PUSH:-false}" _ENABLE_MULTIARCH_BUILD="${_ENABLE_MULTIARCH_BUILD:-false}" _IMAGE_POSTFIX="${_IMAGE_POSTFIX:-""}" From 39a1300d36b67be10657a51d83874798efd7be06 Mon Sep 17 00:00:00 2001 From: Jean-Pierre Busch Date: Thu, 1 Jun 2023 18:34:02 +0200 Subject: [PATCH 098/159] enable single arch push and remove multiarch build env --- action.yml | 7 +++++-- scripts/ci.sh | 10 ++++++---- 2 files changed, 11 insertions(+), 6 deletions(-) diff --git a/action.yml b/action.yml index a19ff5a..a67cc18 100644 --- a/action.yml +++ b/action.yml @@ -50,7 +50,10 @@ inputs: enable-industrial-ci: description: "Enable industrial_ci" default: false - + + enable-singlearch-push: + description: "Enable push of single arch images with [-amd64|-arm64] postfix" + default: false runs: using: "composite" @@ -140,6 +143,6 @@ runs: TAG: ${{ inputs.tag }} DEV_IMAGE_NAME: ${{ inputs.dev-image-name }} DEV_TAG: ${{ inputs.dev-tag }} + ENABLE_SINGLEARCH_PUSH: ${{ inputs.enable-singlearch-push }} _ENABLE_IMAGE_PUSH: true - _ENABLE_MULTIARCH_BUILD: true _IMAGE_POSTFIX: ${{ github.ref != format('refs/heads/{0}', github.event.repository.default_branch) && format('_{0}_ci', steps.slugify-ref-name.outputs.slug) || '' }} diff --git a/scripts/ci.sh b/scripts/ci.sh index 572a03b..72c8c55 100755 --- a/scripts/ci.sh +++ b/scripts/ci.sh @@ -19,8 +19,10 @@ DEV_TAG="${DEV_TAG:-${TAG}-dev}" IMAGE="${IMAGE_NAME}:${TAG}" DEV_IMAGE="${DEV_IMAGE_NAME}:${DEV_TAG}" + +ENABLE_SINGLEARCH_PUSH="${ENABLE_SINGLEARCH_PUSH:-false}" + _ENABLE_IMAGE_PUSH="${_ENABLE_IMAGE_PUSH:-false}" -_ENABLE_MULTIARCH_BUILD="${_ENABLE_MULTIARCH_BUILD:-false}" _IMAGE_POSTFIX="${_IMAGE_POSTFIX:-""}" # write image name for industrial_ci to output @@ -30,14 +32,14 @@ industrial_ci_image="${IMAGE}" [[ -n "${_IMAGE_POSTFIX}" ]] && industrial_ci_image="${industrial_ci_image}${_IMAGE_POSTFIX}" if [[ "${PLATFORM}" != *","* ]]; then industrial_ci_image="${industrial_ci_image}-${PLATFORM}" -elif [[ "${_ENABLE_MULTIARCH_BUILD}" != "true" ]]; then +else industrial_ci_image="${industrial_ci_image}-$(dpkg --print-architecture)" fi echo "INDUSTRIAL_CI_IMAGE=${industrial_ci_image}" >> "${GITHUB_OUTPUT}" # parse (potentially) comma-separated lists to arrays IFS="," read -ra TARGETS <<< "${TARGET}" -if [[ "${_ENABLE_MULTIARCH_BUILD}" == "true" ]]; then +if [[ "${_ENABLE_IMAGE_PUSH}" != "true" || "${ENABLE_SINGLEARCH_PUSH}" == "true" ]]; then IFS="," read -ra PLATFORMS <<< "${PLATFORM}" else PLATFORMS=( "${PLATFORM}" ) @@ -52,7 +54,7 @@ for PLATFORM in "${PLATFORMS[@]}"; do image="${IMAGE}" [[ "${TARGET}" == "dev" ]] && image="${DEV_IMAGE}" [[ -n "${_IMAGE_POSTFIX}" ]] && image="${image}${_IMAGE_POSTFIX}" - [[ "${_ENABLE_MULTIARCH_BUILD}" != "true" ]] && image="${image}-${PLATFORM}" + [[ "${_ENABLE_IMAGE_PUSH}" != "true" || "${ENABLE_SINGLEARCH_PUSH}" == "true" ]] && image="${image}-${PLATFORM}" IMAGE="${image}" build_image close_log_group done From 2d58fa6aa0bf82a9f6f5874f3154d5230697dc90 Mon Sep 17 00:00:00 2001 From: Jean-Pierre Busch Date: Thu, 1 Jun 2023 18:55:07 +0200 Subject: [PATCH 099/159] fix error if docker folder exists --- action.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/action.yml b/action.yml index a67cc18..b946a1c 100644 --- a/action.yml +++ b/action.yml @@ -70,7 +70,7 @@ runs: working-directory: ${{ inputs.build-context }} run: | if ! [[ -d "docker/docker-ros" ]]; then - mkdir docker + mkdir -p docker cp -r ${GITHUB_ACTION_PATH} docker/docker-ros fi From 3b64c4dd4b60ffd7e0c77f5b330a5b79fed29a82 Mon Sep 17 00:00:00 2001 From: Jean-Pierre Busch Date: Thu, 1 Jun 2023 19:24:57 +0200 Subject: [PATCH 100/159] fix if syntax in Dockerfile --- docker/Dockerfile | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/docker/Dockerfile b/docker/Dockerfile index 17505d7..4858477 100644 --- a/docker/Dockerfile +++ b/docker/Dockerfile @@ -53,17 +53,17 @@ ARG GIT_HTTPS_URL=https://gitlab.ika.rwth-aachen.de ARG GIT_HTTPS_USER= ARG GIT_HTTPS_PASSWORD= RUN if [ -n ${GIT_HTTPS_USER} ]; then \ - git config --global url.https://${GIT_HTTPS_USER}:${GIT_HTTPS_PASSWORD}@gitlab.ika.rwth-aachen.de.insteadOf ${GIT_HTTPS_URL} && \ + git config --global url.https://${GIT_HTTPS_USER}:${GIT_HTTPS_PASSWORD}@gitlab.ika.rwth-aachen.de.insteadOf ${GIT_HTTPS_URL} ; \ fi ARG GIT_SSH_PRIVATE_KEY= ARG GIT_SSH_KNOWN_HOST_KEYS= RUN if [ -n ${GIT_SSH_PRIVATE_KEY} ]; then \ echo -e ${GIT_SSH_PRIVATE_KEY} > /tmp/ssh_id && \ chmod 400 /tmp/ssh_id && \ - git config --global core.sshCommand "ssh -i /.ssh_key" ; \ + git config --global core.sshCommand "ssh -i /.ssh_key" && \ mkdir -p ~/.ssh && \ touch ~/.ssh/known_hosts && \ - echo -e ${GIT_SSH_KNOWN_HOST_KEYS} >> ~/.ssh/known_hosts && \ + echo -e ${GIT_SSH_KNOWN_HOST_KEYS} >> ~/.ssh/known_hosts ; \ fi COPY docker/docker-ros/docker/recursive_vcs_import.py /usr/local/bin RUN apt-get update && \ From d88f295608a0bee742d05aba514b9bdcad26f041 Mon Sep 17 00:00:00 2001 From: Jean-Pierre Busch Date: Sat, 3 Jun 2023 00:23:11 +0200 Subject: [PATCH 101/159] first update for gitlab-ci template --- templates/.gitlab-ci.template.yml | 87 ++++++++++++++++++++----------- 1 file changed, 58 insertions(+), 29 deletions(-) diff --git a/templates/.gitlab-ci.template.yml b/templates/.gitlab-ci.template.yml index 68e3179..ab00315 100644 --- a/templates/.gitlab-ci.template.yml +++ b/templates/.gitlab-ci.template.yml @@ -9,25 +9,39 @@ workflow: variables: - IMAGE_DEV_TARGET: ${CI_REGISTRY_IMAGE}:latest-dev - IMAGE_RUN_TARGET: ${CI_REGISTRY_IMAGE}:latest - IMAGE_DEV_CI: ${IMAGE_DEV_TARGET}_${CI_COMMIT_REF_SLUG}_ci - IMAGE_RUN_CI: ${IMAGE_RUN_TARGET}_${CI_COMMIT_REF_SLUG}_ci + TARGET: run # Target stage of Dockerfile (comma-separated list) [dev|run] + PLATFORM: amd64 # Target platform architecture (comma-separated list) [amd64|arm64|...] + BASE_IMAGE: '' # Base image name:tag (required) + COMMAND: '' # Launch command of run image (required if target=run) + IMAGE_NAME: ${CI_REGISTRY_IMAGE} # Image name of run image + IMAGE_TAG: latest # Image tag of run image + DEV_IMAGE_NAME: ${IMAGE_NAME} # Image name of dev image + DEV_IMAGE_TAG: ${IMAGE_TAG}-dev # Image tag of dev image + BUILD_CONTEXT: . # Build context of Docker build process + REGISTRY: ${CI_REGISTRY} # Docker registry to push images to + REGISTRY_USERNAME: ${CI_REGISTRY_USER} # Docker registry username + REGISTRY_PASSWORD: ${CI_REGISTRY_PASSWORD} # Docker registry password + ENABLE_INDUSTRIAL_CI: false # Enable industrial_ci + ENABLE_SINGLEARCH_PUSH: false # Enable push of single arch images with [-amd64|-arm64] postfix + + RUN_IMAGE: ${IMAGE_NAME}:${IMAGE_TAG} + DEV_IMAGE: ${DEV_IMAGE_NAME}:${DEV_IMAGE_TAG} + + IMAGE_DEV_CI: ${DEV_IMAGE}_${CI_COMMIT_REF_SLUG}_ci + IMAGE_RUN_CI: ${RUN_IMAGE}_${CI_COMMIT_REF_SLUG}_ci IMAGE_DEV_CI_AMD64: ${IMAGE_DEV_CI}-amd64 IMAGE_DEV_CI_ARM64: ${IMAGE_DEV_CI}-arm64 IMAGE_RUN_CI_AMD64: ${IMAGE_RUN_CI}-amd64 IMAGE_RUN_CI_ARM64: ${IMAGE_RUN_CI}-arm64 - IMAGE_DEV_LATEST: ${CI_REGISTRY_IMAGE}:latest-dev - IMAGE_RUN_LATEST: ${CI_REGISTRY_IMAGE}:latest - IMAGE_DEV_TARGET_TAG: ${IMAGE_DEV_TARGET}-${CI_COMMIT_TAG}-dev - IMAGE_RUN_TARGET_TAG: ${IMAGE_RUN_TARGET}-${CI_COMMIT_TAG} - IMAGE_DEV_TAG: ${CI_REGISTRY_IMAGE}:${CI_COMMIT_TAG}-dev - IMAGE_RUN_TAG: ${CI_REGISTRY_IMAGE}:${CI_COMMIT_TAG} + IMAGE_DEV_LATEST: ${DEV_IMAGE_NAME}:latest-dev + IMAGE_RUN_LATEST: ${IMAGE_NAME}:latest + IMAGE_DEV_TARGET_TAG: ${DEV_IMAGE}-${CI_COMMIT_TAG}-dev + IMAGE_RUN_TARGET_TAG: ${RUN_IMAGE}-${CI_COMMIT_TAG} + IMAGE_DEV_TAG: ${DEV_IMAGE_NAME}:${CI_COMMIT_TAG}-dev + IMAGE_RUN_TAG: ${IMAGE_NAME}:${CI_COMMIT_TAG} PUSH_AS_LATEST: 'false' # ----- DOCKER_ROS_GIT_REF: main - DOCKER_DIR: docker - ROS_DIR: . DISABLE_ARCH_AMD64: 'false' DISABLE_ARCH_ARM64: 'false' DISABLE_INDUSTRIAL_CI: 'false' @@ -57,20 +71,21 @@ default: - amd64 before_script: - apk add bash + - cd ${BUILD_CONTEXT} - |- - if [[ ! -d $DOCKER_DIR/docker-ros ]]; then - git config --global url.${CI_SERVER_PROTOCOL}://gitlab-ci-token:${CI_JOB_TOKEN}@${CI_SERVER_HOST}:${CI_SERVER_PORT}.insteadOf ${CI_SERVER_URL} - git clone --depth=1 https://gitlab.ika.rwth-aachen.de/fb-fi/ops/docker-ros.git $DOCKER_DIR/docker-ros - cd $DOCKER_DIR/docker-ros - git fetch origin $DOCKER_ROS_GIT_REF + if [[ ! -d $docker/docker-ros ]]; then + mkdir -p docker + git config --global url.https://${GIT_HTTPS_USER}:${GIT_HTTPS_PASSWORD}@${CI_SERVER_HOST}:${CI_SERVER_PORT}.insteadOf ${CI_SERVER_URL} + git clone --depth=1 https://gitlab.ika.rwth-aachen.de/fb-fi/ops/docker-ros.git docker/docker-ros + cd docker/docker-ros + git fetch origin ${DOCKER_ROS_GIT_REF} git checkout FETCH_HEAD cd - fi - - docker login -u $CI_REGISTRY_USER -p $CI_REGISTRY_PASSWORD $CI_REGISTRY + - docker login -u ${REGISTRY_USERNAME} -p ${REGISTRY_PASSWORD} ${REGISTRY} - docker context create buildx-context - docker buildx create --use buildx-context - - cd $DOCKER_DIR - + - cd docker .build: script: @@ -84,9 +99,12 @@ dev-amd64: - if: $DISABLE_ARCH_AMD64 != 'true' variables: PLATFORM: linux/amd64 + BASE_IMAGE: ${BASE_IMAGE} TARGET: dev IMAGE: ${IMAGE_DEV_CI_AMD64} - CACHE_FROM: ${IMAGE_DEV_CI_AMD64} + GIT_HTTPS_USER: ${GIT_HTTPS_USER} + GIT_HTTPS_PASSWORD: ${GIT_HTTPS_PASSWORD} + _ENABLE_IMAGE_PUSH: true dev-arm64: stage: Build dev Images @@ -96,9 +114,12 @@ dev-arm64: - if: $DISABLE_ARCH_ARM64 != 'true' variables: PLATFORM: linux/arm64 + BASE_IMAGE: ${BASE_IMAGE} TARGET: dev IMAGE: ${IMAGE_DEV_CI_ARM64} - CACHE_FROM: ${IMAGE_DEV_CI_ARM64} + GIT_HTTPS_USER: ${GIT_HTTPS_USER} + GIT_HTTPS_PASSWORD: ${GIT_HTTPS_PASSWORD} + _ENABLE_IMAGE_PUSH: true run-amd64: stage: Build run Images @@ -108,9 +129,13 @@ run-amd64: - if: $DISABLE_ARCH_AMD64 != 'true' variables: PLATFORM: linux/amd64 + BASE_IMAGE: ${BASE_IMAGE} + COMMAND: ${COMMAND} TARGET: run IMAGE: ${IMAGE_RUN_CI_AMD64} - CACHE_FROM: ${IMAGE_DEV_CI_AMD64} + GIT_HTTPS_USER: ${GIT_HTTPS_USER} + GIT_HTTPS_PASSWORD: ${GIT_HTTPS_PASSWORD} + _ENABLE_IMAGE_PUSH: true run-arm64: stage: Build run Images @@ -121,23 +146,27 @@ run-arm64: - if: $DISABLE_ARCH_ARM64 != 'true' variables: PLATFORM: linux/arm64 + BASE_IMAGE: ${BASE_IMAGE} + COMMAND: ${COMMAND} TARGET: run IMAGE: ${IMAGE_RUN_CI_ARM64} - CACHE_FROM: ${IMAGE_DEV_CI_ARM64} + GIT_HTTPS_USER: ${GIT_HTTPS_USER} + GIT_HTTPS_PASSWORD: ${GIT_HTTPS_PASSWORD} + _ENABLE_IMAGE_PUSH: true .test: variables: - UPSTREAM_WORKSPACE: $ROS_DIR/.repos - TARGET_WORKSPACE: $ROS_DIR + UPSTREAM_WORKSPACE: ${BUILD_CONTEXT}/.repos + TARGET_WORKSPACE: ${BUILD_CONTEXT} ADDITIONAL_DEBS: git - AFTER_INIT_EMBED: git config --global url.${CI_SERVER_PROTOCOL}://gitlab-ci-token:${CI_JOB_TOKEN}@${CI_SERVER_HOST}:${CI_SERVER_PORT}.insteadOf ${CI_SERVER_URL} + AFTER_INIT_EMBED: git config --global url.https://${GIT_HTTPS_USER}:${GIT_HTTPS_PASSWORD}@${CI_SERVER_HOST}:${CI_SERVER_PORT}.insteadOf ${CI_SERVER_URL} DOCKER_RUN_OPTS: -u root:root before_script: - - docker login -u $CI_REGISTRY_USER -p $CI_REGISTRY_PASSWORD $CI_REGISTRY + - docker login -u ${REGISTRY_USERNAME} -p ${REGISTRY_PASSWORD} ${REGISTRY} - apk add --update bash coreutils grep tar - git clone --branch master --depth 1 https://github.com/ros-industrial/industrial_ci.git .industrial_ci - - test -f $ROS_DIR/.repos || echo "repositories:" > $ROS_DIR/.repos + - test -f ${BUILD_CONTEXT}/.repos || echo "repositories:" > ${BUILD_CONTEXT}/.repos script: .industrial_ci/gitlab.sh Test dev-amd64: From b963306a0f8eccf941f55aa720759d656ae9271b Mon Sep 17 00:00:00 2001 From: Jean-Pierre Busch Date: Sat, 3 Jun 2023 00:31:23 +0200 Subject: [PATCH 102/159] fix invalid gitlab-ci.yml --- templates/.gitlab-ci.template.yml | 14 +++++++------- 1 file changed, 7 insertions(+), 7 deletions(-) diff --git a/templates/.gitlab-ci.template.yml b/templates/.gitlab-ci.template.yml index ab00315..0d561a1 100644 --- a/templates/.gitlab-ci.template.yml +++ b/templates/.gitlab-ci.template.yml @@ -21,8 +21,8 @@ variables: REGISTRY: ${CI_REGISTRY} # Docker registry to push images to REGISTRY_USERNAME: ${CI_REGISTRY_USER} # Docker registry username REGISTRY_PASSWORD: ${CI_REGISTRY_PASSWORD} # Docker registry password - ENABLE_INDUSTRIAL_CI: false # Enable industrial_ci - ENABLE_SINGLEARCH_PUSH: false # Enable push of single arch images with [-amd64|-arm64] postfix + ENABLE_INDUSTRIAL_CI: 'false' # Enable industrial_ci + ENABLE_SINGLEARCH_PUSH: 'false' # Enable push of single arch images with [-amd64|-arm64] postfix RUN_IMAGE: ${IMAGE_NAME}:${IMAGE_TAG} DEV_IMAGE: ${DEV_IMAGE_NAME}:${DEV_IMAGE_TAG} @@ -104,7 +104,7 @@ dev-amd64: IMAGE: ${IMAGE_DEV_CI_AMD64} GIT_HTTPS_USER: ${GIT_HTTPS_USER} GIT_HTTPS_PASSWORD: ${GIT_HTTPS_PASSWORD} - _ENABLE_IMAGE_PUSH: true + _ENABLE_IMAGE_PUSH: 'true' dev-arm64: stage: Build dev Images @@ -119,7 +119,7 @@ dev-arm64: IMAGE: ${IMAGE_DEV_CI_ARM64} GIT_HTTPS_USER: ${GIT_HTTPS_USER} GIT_HTTPS_PASSWORD: ${GIT_HTTPS_PASSWORD} - _ENABLE_IMAGE_PUSH: true + _ENABLE_IMAGE_PUSH: 'true' run-amd64: stage: Build run Images @@ -135,7 +135,7 @@ run-amd64: IMAGE: ${IMAGE_RUN_CI_AMD64} GIT_HTTPS_USER: ${GIT_HTTPS_USER} GIT_HTTPS_PASSWORD: ${GIT_HTTPS_PASSWORD} - _ENABLE_IMAGE_PUSH: true + _ENABLE_IMAGE_PUSH: 'true' run-arm64: stage: Build run Images @@ -152,7 +152,7 @@ run-arm64: IMAGE: ${IMAGE_RUN_CI_ARM64} GIT_HTTPS_USER: ${GIT_HTTPS_USER} GIT_HTTPS_PASSWORD: ${GIT_HTTPS_PASSWORD} - _ENABLE_IMAGE_PUSH: true + _ENABLE_IMAGE_PUSH: 'true' .test: @@ -267,4 +267,4 @@ Push tag: - if: $CI_COMMIT_TAG && $PUSH_AS_LATEST == 'true' variables: IMG_DEV: ${IMAGE_DEV_TAG} - IMG_RUN: ${IMAGE_RUN_TAG} + IMG_RUN: ${IMAGE_RUN_TAG} \ No newline at end of file From d71c4a17fbd019879ef729c1a08cf100fe7593a7 Mon Sep 17 00:00:00 2001 From: Jean-Pierre Busch <110477057+jpbusch@users.noreply.github.com> Date: Sun, 4 Jun 2023 22:39:17 +0200 Subject: [PATCH 103/159] change docker-ros path of gitlab-ci template to github --- templates/.gitlab-ci.template.yml | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) diff --git a/templates/.gitlab-ci.template.yml b/templates/.gitlab-ci.template.yml index 0d561a1..3c5b6b6 100644 --- a/templates/.gitlab-ci.template.yml +++ b/templates/.gitlab-ci.template.yml @@ -75,8 +75,7 @@ default: - |- if [[ ! -d $docker/docker-ros ]]; then mkdir -p docker - git config --global url.https://${GIT_HTTPS_USER}:${GIT_HTTPS_PASSWORD}@${CI_SERVER_HOST}:${CI_SERVER_PORT}.insteadOf ${CI_SERVER_URL} - git clone --depth=1 https://gitlab.ika.rwth-aachen.de/fb-fi/ops/docker-ros.git docker/docker-ros + git clone --depth=1 https://github.com/ika-rwth-aachen/docker-ros.git docker/docker-ros cd docker/docker-ros git fetch origin ${DOCKER_ROS_GIT_REF} git checkout FETCH_HEAD @@ -267,4 +266,4 @@ Push tag: - if: $CI_COMMIT_TAG && $PUSH_AS_LATEST == 'true' variables: IMG_DEV: ${IMAGE_DEV_TAG} - IMG_RUN: ${IMAGE_RUN_TAG} \ No newline at end of file + IMG_RUN: ${IMAGE_RUN_TAG} From 1ce8589dc525a98aebb228feeee9a967d75a7569 Mon Sep 17 00:00:00 2001 From: Jean-Pierre Busch <110477057+jpbusch@users.noreply.github.com> Date: Sun, 4 Jun 2023 23:00:31 +0200 Subject: [PATCH 104/159] fix psth to build.sh in .gitlab-ci.template.yml --- templates/.gitlab-ci.template.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/templates/.gitlab-ci.template.yml b/templates/.gitlab-ci.template.yml index 3c5b6b6..62aa9f2 100644 --- a/templates/.gitlab-ci.template.yml +++ b/templates/.gitlab-ci.template.yml @@ -88,7 +88,7 @@ default: .build: script: - - ./docker-ros/build.sh + - ./docker-ros/scripts/build.sh - docker push ${IMAGE} dev-amd64: From 0ffbbb55d80824ed4d2c9f2a3c89563a661411bc Mon Sep 17 00:00:00 2001 From: Jean-Pierre Busch Date: Mon, 5 Jun 2023 09:44:14 +0200 Subject: [PATCH 105/159] gitlab-ci - parse vars to build.sh --- templates/.gitlab-ci.template.yml | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/templates/.gitlab-ci.template.yml b/templates/.gitlab-ci.template.yml index 62aa9f2..707aa67 100644 --- a/templates/.gitlab-ci.template.yml +++ b/templates/.gitlab-ci.template.yml @@ -88,7 +88,8 @@ default: .build: script: - - ./docker-ros/scripts/build.sh + - PLATFORM=${PLATFORM} BASE_IMAGE=${BASE_IMAGE} TARGET=${TARGET} IMAGE=${IMAGE} COMMAND=${COMMAND} GIT_HTTPS_USER=${GIT_HTTPS_USER} GIT_HTTPS_PASSWORD=${GIT_HTTPS_PASSWORD} _ENABLE_IMAGE_PUSH=${_ENABLE_IMAGE_PUSH} ./docker-ros/scripts/build.sh + - echo "CMD is ${COMMAND}" - docker push ${IMAGE} dev-amd64: From ab6145872749e5f8772d9f101f35a1d497041e57 Mon Sep 17 00:00:00 2001 From: Jean-Pierre Busch Date: Mon, 5 Jun 2023 10:16:45 +0200 Subject: [PATCH 106/159] gitlab-ci.yml - remove duplicated vars --- templates/.gitlab-ci.template.yml | 15 +-------------- 1 file changed, 1 insertion(+), 14 deletions(-) diff --git a/templates/.gitlab-ci.template.yml b/templates/.gitlab-ci.template.yml index 707aa67..0b4652a 100644 --- a/templates/.gitlab-ci.template.yml +++ b/templates/.gitlab-ci.template.yml @@ -88,8 +88,7 @@ default: .build: script: - - PLATFORM=${PLATFORM} BASE_IMAGE=${BASE_IMAGE} TARGET=${TARGET} IMAGE=${IMAGE} COMMAND=${COMMAND} GIT_HTTPS_USER=${GIT_HTTPS_USER} GIT_HTTPS_PASSWORD=${GIT_HTTPS_PASSWORD} _ENABLE_IMAGE_PUSH=${_ENABLE_IMAGE_PUSH} ./docker-ros/scripts/build.sh - - echo "CMD is ${COMMAND}" + - ./docker-ros/scripts/build.sh - docker push ${IMAGE} dev-amd64: @@ -99,11 +98,8 @@ dev-amd64: - if: $DISABLE_ARCH_AMD64 != 'true' variables: PLATFORM: linux/amd64 - BASE_IMAGE: ${BASE_IMAGE} TARGET: dev IMAGE: ${IMAGE_DEV_CI_AMD64} - GIT_HTTPS_USER: ${GIT_HTTPS_USER} - GIT_HTTPS_PASSWORD: ${GIT_HTTPS_PASSWORD} _ENABLE_IMAGE_PUSH: 'true' dev-arm64: @@ -114,11 +110,8 @@ dev-arm64: - if: $DISABLE_ARCH_ARM64 != 'true' variables: PLATFORM: linux/arm64 - BASE_IMAGE: ${BASE_IMAGE} TARGET: dev IMAGE: ${IMAGE_DEV_CI_ARM64} - GIT_HTTPS_USER: ${GIT_HTTPS_USER} - GIT_HTTPS_PASSWORD: ${GIT_HTTPS_PASSWORD} _ENABLE_IMAGE_PUSH: 'true' run-amd64: @@ -129,12 +122,9 @@ run-amd64: - if: $DISABLE_ARCH_AMD64 != 'true' variables: PLATFORM: linux/amd64 - BASE_IMAGE: ${BASE_IMAGE} COMMAND: ${COMMAND} TARGET: run IMAGE: ${IMAGE_RUN_CI_AMD64} - GIT_HTTPS_USER: ${GIT_HTTPS_USER} - GIT_HTTPS_PASSWORD: ${GIT_HTTPS_PASSWORD} _ENABLE_IMAGE_PUSH: 'true' run-arm64: @@ -146,12 +136,9 @@ run-arm64: - if: $DISABLE_ARCH_ARM64 != 'true' variables: PLATFORM: linux/arm64 - BASE_IMAGE: ${BASE_IMAGE} COMMAND: ${COMMAND} TARGET: run IMAGE: ${IMAGE_RUN_CI_ARM64} - GIT_HTTPS_USER: ${GIT_HTTPS_USER} - GIT_HTTPS_PASSWORD: ${GIT_HTTPS_PASSWORD} _ENABLE_IMAGE_PUSH: 'true' From 1a670ef8ae38c41d4ead03e979cf6b9c9c854baf Mon Sep 17 00:00:00 2001 From: Jean-Pierre Busch Date: Mon, 5 Jun 2023 10:17:01 +0200 Subject: [PATCH 107/159] temporary deactivate github workflow --- .github/workflows/main.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/main.yml b/.github/workflows/main.yml index 8e13a6a..aa2421a 100644 --- a/.github/workflows/main.yml +++ b/.github/workflows/main.yml @@ -1,4 +1,4 @@ -on: [push] +on: [pull_request] jobs: trigger-docker-ros-ci-ros1: From 5990552d0e3fbeeeae7ab2562b2010ec6952a0a3 Mon Sep 17 00:00:00 2001 From: Jean-Pierre Busch Date: Mon, 5 Jun 2023 10:17:44 +0200 Subject: [PATCH 108/159] use enable_industrial_ci instead of old var --- templates/.gitlab-ci.template.yml | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) diff --git a/templates/.gitlab-ci.template.yml b/templates/.gitlab-ci.template.yml index 0b4652a..8328d0a 100644 --- a/templates/.gitlab-ci.template.yml +++ b/templates/.gitlab-ci.template.yml @@ -44,7 +44,6 @@ variables: DOCKER_ROS_GIT_REF: main DISABLE_ARCH_AMD64: 'false' DISABLE_ARCH_ARM64: 'false' - DISABLE_INDUSTRIAL_CI: 'false' DISABLE_PUSH: 'false' GIT_HTTPS_USER: gitlab-ci-token GIT_HTTPS_PASSWORD: $CI_JOB_TOKEN @@ -163,7 +162,7 @@ Test dev-amd64: - job: dev-amd64 optional: true rules: - - if: $DISABLE_INDUSTRIAL_CI != 'true' && $DISABLE_ARCH_AMD64 != 'true' + - if: $ENABLE_INDUSTRIAL_CI == 'true' && $DISABLE_ARCH_AMD64 != 'true' variables: DOCKER_IMAGE: ${IMAGE_DEV_CI_AMD64} @@ -175,7 +174,7 @@ Test dev-arm64: - job: dev-arm64 optional: true rules: - - if: $DISABLE_INDUSTRIAL_CI != 'true' && $DISABLE_ARCH_ARM64 != 'true' + - if: $ENABLE_INDUSTRIAL_CI == 'true' && $DISABLE_ARCH_ARM64 != 'true' variables: DOCKER_IMAGE: ${IMAGE_DEV_CI_ARM64} From 544dd2917524fd12bacb19028d662582705806a1 Mon Sep 17 00:00:00 2001 From: Jean-Pierre Busch Date: Mon, 5 Jun 2023 11:25:30 +0200 Subject: [PATCH 109/159] test prints --- templates/.gitlab-ci.template.yml | 2 ++ 1 file changed, 2 insertions(+) diff --git a/templates/.gitlab-ci.template.yml b/templates/.gitlab-ci.template.yml index 8328d0a..7964501 100644 --- a/templates/.gitlab-ci.template.yml +++ b/templates/.gitlab-ci.template.yml @@ -84,6 +84,8 @@ default: - docker context create buildx-context - docker buildx create --use buildx-context - cd docker + - ls -al docker-ros/ + - ls -al docker-ros/docker/ .build: script: From b68b1d0dc29b2f38ba36f0706e6427538ab64951 Mon Sep 17 00:00:00 2001 From: Jean-Pierre Busch Date: Mon, 5 Jun 2023 11:54:17 +0200 Subject: [PATCH 110/159] gitlab-ci.yml - change workdir to context --- templates/.gitlab-ci.template.yml | 5 +---- 1 file changed, 1 insertion(+), 4 deletions(-) diff --git a/templates/.gitlab-ci.template.yml b/templates/.gitlab-ci.template.yml index 7964501..998198a 100644 --- a/templates/.gitlab-ci.template.yml +++ b/templates/.gitlab-ci.template.yml @@ -83,13 +83,10 @@ default: - docker login -u ${REGISTRY_USERNAME} -p ${REGISTRY_PASSWORD} ${REGISTRY} - docker context create buildx-context - docker buildx create --use buildx-context - - cd docker - - ls -al docker-ros/ - - ls -al docker-ros/docker/ .build: script: - - ./docker-ros/scripts/build.sh + - ./docker/docker-ros/scripts/build.sh - docker push ${IMAGE} dev-amd64: From b6ba04556de37fa02bab72a82f6b1e0ed1928dc5 Mon Sep 17 00:00:00 2001 From: Jean-Pierre Busch Date: Mon, 5 Jun 2023 12:20:43 +0200 Subject: [PATCH 111/159] gitlab-ci.yml - do not push image with buildx --- templates/.gitlab-ci.template.yml | 4 ---- 1 file changed, 4 deletions(-) diff --git a/templates/.gitlab-ci.template.yml b/templates/.gitlab-ci.template.yml index 998198a..a926626 100644 --- a/templates/.gitlab-ci.template.yml +++ b/templates/.gitlab-ci.template.yml @@ -98,7 +98,6 @@ dev-amd64: PLATFORM: linux/amd64 TARGET: dev IMAGE: ${IMAGE_DEV_CI_AMD64} - _ENABLE_IMAGE_PUSH: 'true' dev-arm64: stage: Build dev Images @@ -110,7 +109,6 @@ dev-arm64: PLATFORM: linux/arm64 TARGET: dev IMAGE: ${IMAGE_DEV_CI_ARM64} - _ENABLE_IMAGE_PUSH: 'true' run-amd64: stage: Build run Images @@ -123,7 +121,6 @@ run-amd64: COMMAND: ${COMMAND} TARGET: run IMAGE: ${IMAGE_RUN_CI_AMD64} - _ENABLE_IMAGE_PUSH: 'true' run-arm64: stage: Build run Images @@ -137,7 +134,6 @@ run-arm64: COMMAND: ${COMMAND} TARGET: run IMAGE: ${IMAGE_RUN_CI_ARM64} - _ENABLE_IMAGE_PUSH: 'true' .test: From 52b6ebdbd65d8fd2ab4c997ab57721eb33f11290 Mon Sep 17 00:00:00 2001 From: Jean-Pierre Busch Date: Mon, 5 Jun 2023 15:02:23 +0200 Subject: [PATCH 112/159] gitlab-ci.yml - remove DISABLE_ARCH vars --- templates/.gitlab-ci.template.yml | 53 +++++++++++++++++++------------ 1 file changed, 32 insertions(+), 21 deletions(-) diff --git a/templates/.gitlab-ci.template.yml b/templates/.gitlab-ci.template.yml index a926626..6ad719e 100644 --- a/templates/.gitlab-ci.template.yml +++ b/templates/.gitlab-ci.template.yml @@ -10,7 +10,7 @@ workflow: variables: TARGET: run # Target stage of Dockerfile (comma-separated list) [dev|run] - PLATFORM: amd64 # Target platform architecture (comma-separated list) [amd64|arm64|...] + PLATFORM: '' # Target platform architecture (comma-separated list) [amd64|arm64|...] BASE_IMAGE: '' # Base image name:tag (required) COMMAND: '' # Launch command of run image (required if target=run) IMAGE_NAME: ${CI_REGISTRY_IMAGE} # Image name of run image @@ -42,8 +42,6 @@ variables: PUSH_AS_LATEST: 'false' # ----- DOCKER_ROS_GIT_REF: main - DISABLE_ARCH_AMD64: 'false' - DISABLE_ARCH_ARM64: 'false' DISABLE_PUSH: 'false' GIT_HTTPS_USER: gitlab-ci-token GIT_HTTPS_PASSWORD: $CI_JOB_TOKEN @@ -93,9 +91,9 @@ dev-amd64: stage: Build dev Images extends: .build rules: - - if: $DISABLE_ARCH_AMD64 != 'true' + - if: ${PLATFORM} =~ 'amd64' && ${TARGET} =~ 'dev' variables: - PLATFORM: linux/amd64 + PLATFORM: amd64 TARGET: dev IMAGE: ${IMAGE_DEV_CI_AMD64} @@ -104,20 +102,22 @@ dev-arm64: extends: .build tags: [privileged, arm64] rules: - - if: $DISABLE_ARCH_ARM64 != 'true' + - if: ${PLATFORM} =~ 'arm64' && ${TARGET} =~ 'dev' variables: - PLATFORM: linux/arm64 + PLATFORM: arm64 TARGET: dev IMAGE: ${IMAGE_DEV_CI_ARM64} run-amd64: stage: Build run Images extends: .build - needs: [dev-amd64] + needs: + - job: dev-amd64 + optional: true rules: - - if: $DISABLE_ARCH_AMD64 != 'true' + - if: ${PLATFORM} =~ 'amd64' && ${TARGET} =~ 'run' variables: - PLATFORM: linux/amd64 + PLATFORM: amd64 COMMAND: ${COMMAND} TARGET: run IMAGE: ${IMAGE_RUN_CI_AMD64} @@ -126,11 +126,13 @@ run-arm64: stage: Build run Images extends: .build tags: [privileged, arm64] - needs: [dev-arm64] + needs: + - job: dev-arm64 + optional: true rules: - - if: $DISABLE_ARCH_ARM64 != 'true' + - if: ${PLATFORM} =~ 'arm64' && ${TARGET} =~ 'run' variables: - PLATFORM: linux/arm64 + PLATFORM: arm64 COMMAND: ${COMMAND} TARGET: run IMAGE: ${IMAGE_RUN_CI_ARM64} @@ -157,7 +159,7 @@ Test dev-amd64: - job: dev-amd64 optional: true rules: - - if: $ENABLE_INDUSTRIAL_CI == 'true' && $DISABLE_ARCH_AMD64 != 'true' + - if: $ENABLE_INDUSTRIAL_CI == 'true' && ${PLATFORM} =~ 'amd64' variables: DOCKER_IMAGE: ${IMAGE_DEV_CI_AMD64} @@ -169,7 +171,7 @@ Test dev-arm64: - job: dev-arm64 optional: true rules: - - if: $ENABLE_INDUSTRIAL_CI == 'true' && $DISABLE_ARCH_ARM64 != 'true' + - if: $ENABLE_INDUSTRIAL_CI == 'true' && ${PLATFORM} =~ 'arm64' variables: DOCKER_IMAGE: ${IMAGE_DEV_CI_ARM64} @@ -189,14 +191,23 @@ Test dev-arm64: - job: Test dev-arm64 optional: true rules: - - if: $DISABLE_PUSH == 'true' || $DISABLE_ARCH_AMD64 == 'true' && $DISABLE_ARCH_ARM64 == 'true' + - if: ${PLATFORM} == '' || ${TARGET} == '' when: never script: - - if [ $DISABLE_ARCH_AMD64 != "true" ] && [ $DISABLE_ARCH_ARM64 != "true" ]; then docker manifest create ${IMG_DEV} --amend ${IMAGE_DEV_CI_AMD64} --amend ${IMAGE_DEV_CI_ARM64} && docker manifest create ${IMG_RUN} --amend ${IMAGE_RUN_CI_AMD64} --amend ${IMAGE_RUN_CI_ARM64}; fi - - if [ $DISABLE_ARCH_AMD64 != "true" ] && [ $DISABLE_ARCH_ARM64 = "true" ]; then docker manifest create ${IMG_DEV} --amend ${IMAGE_DEV_CI_AMD64} && docker manifest create ${IMG_RUN} --amend ${IMAGE_RUN_CI_AMD64}; fi - - if [ $DISABLE_ARCH_AMD64 = "true" ] && [ $DISABLE_ARCH_ARM64 != "true" ]; then docker manifest create ${IMG_DEV} --amend ${IMAGE_DEV_CI_ARM64} && docker manifest create ${IMG_RUN} --amend ${IMAGE_RUN_CI_ARM64}; fi - - docker manifest push ${IMG_DEV} - - docker manifest push ${IMG_RUN} + - |- + if [[ ${PLATFORM} =~ 'amd64' && ${PLATFORM} =~ 'arm64' ]]; then + [[ ${TARGET} =~ 'dev' ]] && docker manifest create ${IMG_DEV} --amend ${IMAGE_DEV_CI_AMD64} --amend ${IMAGE_DEV_CI_ARM64} + [[ ${TARGET} =~ 'run' ]] && docker manifest create ${IMG_RUN} --amend ${IMAGE_RUN_CI_AMD64} --amend ${IMAGE_RUN_CI_ARM64} + elif [[ ${PLATFORM} == 'amd64' ]]; then + [[ ${TARGET} =~ 'dev' ]] && docker manifest create ${IMG_DEV} --amend ${IMAGE_DEV_CI_AMD64} + [[ ${TARGET} =~ 'run' ]] && docker manifest create ${IMG_RUN} --amend ${IMAGE_RUN_CI_AMD64} + elif [[ ${PLATFORM} == 'amd64' ]]; then + [[ ${TARGET} =~ 'dev' ]] && docker manifest create ${IMG_DEV} --amend ${IMAGE_DEV_CI_ARM64} + [[ ${TARGET} =~ 'run' ]] && docker manifest create ${IMG_RUN} --amend ${IMAGE_RUN_CI_ARM64} + fi + - |- + [[ ${TARGET} =~ 'dev' ]] && docker manifest push ${IMG_DEV} + [[ ${TARGET} =~ 'dev' ]] && docker manifest push ${IMG_RUN} Push CI: stage: Push Multi-Arch Images From 4a00f6dc9a572371765c41945df3b4a6f1c894ac Mon Sep 17 00:00:00 2001 From: Jean-Pierre Busch Date: Mon, 5 Jun 2023 15:02:53 +0200 Subject: [PATCH 113/159] install qemu if needed --- templates/.gitlab-ci.template.yml | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/templates/.gitlab-ci.template.yml b/templates/.gitlab-ci.template.yml index 6ad719e..dac7317 100644 --- a/templates/.gitlab-ci.template.yml +++ b/templates/.gitlab-ci.template.yml @@ -78,6 +78,10 @@ default: git checkout FETCH_HEAD cd - fi + - |- + if [[ $(dpkg --print-architecture) != ${PLATFORM} ]]; then + docker run --rm --privileged multiarch/qemu-user-static --reset -p yes + fi - docker login -u ${REGISTRY_USERNAME} -p ${REGISTRY_PASSWORD} ${REGISTRY} - docker context create buildx-context - docker buildx create --use buildx-context From f4194c35142036079725a594d5e6a56fd7b4f6bb Mon Sep 17 00:00:00 2001 From: Jean-Pierre Busch Date: Mon, 5 Jun 2023 15:03:48 +0200 Subject: [PATCH 114/159] gitlab-ci.yml - add GIT_HTTPS_SERVER --- templates/.gitlab-ci.template.yml | 9 +++++---- 1 file changed, 5 insertions(+), 4 deletions(-) diff --git a/templates/.gitlab-ci.template.yml b/templates/.gitlab-ci.template.yml index dac7317..2f6f7b7 100644 --- a/templates/.gitlab-ci.template.yml +++ b/templates/.gitlab-ci.template.yml @@ -23,6 +23,10 @@ variables: REGISTRY_PASSWORD: ${CI_REGISTRY_PASSWORD} # Docker registry password ENABLE_INDUSTRIAL_CI: 'false' # Enable industrial_ci ENABLE_SINGLEARCH_PUSH: 'false' # Enable push of single arch images with [-amd64|-arm64] postfix + PUSH_AS_LATEST: 'false' # Push image additionally with tag 'latest' + GIT_HTTPS_SERVER: ${CI_SERVER_HOST}:${CI_SERVER_PORT} # git server address for private repositories without protocol (e.g. github.com) + GIT_HTTPS_USER: gitlab-ci-token # git https username for private repository access + GIT_HTTPS_PASSWORD: ${CI_JOB_TOKEN} # git https password/token for private repository access RUN_IMAGE: ${IMAGE_NAME}:${IMAGE_TAG} DEV_IMAGE: ${DEV_IMAGE_NAME}:${DEV_IMAGE_TAG} @@ -39,12 +43,9 @@ variables: IMAGE_RUN_TARGET_TAG: ${RUN_IMAGE}-${CI_COMMIT_TAG} IMAGE_DEV_TAG: ${DEV_IMAGE_NAME}:${CI_COMMIT_TAG}-dev IMAGE_RUN_TAG: ${IMAGE_NAME}:${CI_COMMIT_TAG} - PUSH_AS_LATEST: 'false' # ----- DOCKER_ROS_GIT_REF: main DISABLE_PUSH: 'false' - GIT_HTTPS_USER: gitlab-ci-token - GIT_HTTPS_PASSWORD: $CI_JOB_TOKEN # ----- GIT_SUBMODULE_STRATEGY: recursive DOCKER_DRIVER: overlay2 @@ -147,7 +148,7 @@ run-arm64: UPSTREAM_WORKSPACE: ${BUILD_CONTEXT}/.repos TARGET_WORKSPACE: ${BUILD_CONTEXT} ADDITIONAL_DEBS: git - AFTER_INIT_EMBED: git config --global url.https://${GIT_HTTPS_USER}:${GIT_HTTPS_PASSWORD}@${CI_SERVER_HOST}:${CI_SERVER_PORT}.insteadOf ${CI_SERVER_URL} + AFTER_INIT_EMBED: git config --global url.https://${GIT_HTTPS_USER}:${GIT_HTTPS_PASSWORD}@${GIT_HTTPS_SERVER}.insteadOf https://${GIT_HTTPS_SERVER} DOCKER_RUN_OPTS: -u root:root before_script: - docker login -u ${REGISTRY_USERNAME} -p ${REGISTRY_PASSWORD} ${REGISTRY} From 5b177b5843d00544bc5b5104f0ffcbfdcb374b48 Mon Sep 17 00:00:00 2001 From: Jean-Pierre Busch Date: Mon, 5 Jun 2023 15:23:52 +0200 Subject: [PATCH 115/159] gitlab-ci.yml - prefix internal vars with "_" --- templates/.gitlab-ci.template.yml | 106 +++++++++++++++--------------- 1 file changed, 53 insertions(+), 53 deletions(-) diff --git a/templates/.gitlab-ci.template.yml b/templates/.gitlab-ci.template.yml index 2f6f7b7..775ec4d 100644 --- a/templates/.gitlab-ci.template.yml +++ b/templates/.gitlab-ci.template.yml @@ -9,40 +9,40 @@ workflow: variables: - TARGET: run # Target stage of Dockerfile (comma-separated list) [dev|run] - PLATFORM: '' # Target platform architecture (comma-separated list) [amd64|arm64|...] - BASE_IMAGE: '' # Base image name:tag (required) - COMMAND: '' # Launch command of run image (required if target=run) - IMAGE_NAME: ${CI_REGISTRY_IMAGE} # Image name of run image - IMAGE_TAG: latest # Image tag of run image - DEV_IMAGE_NAME: ${IMAGE_NAME} # Image name of dev image - DEV_IMAGE_TAG: ${IMAGE_TAG}-dev # Image tag of dev image - BUILD_CONTEXT: . # Build context of Docker build process - REGISTRY: ${CI_REGISTRY} # Docker registry to push images to - REGISTRY_USERNAME: ${CI_REGISTRY_USER} # Docker registry username - REGISTRY_PASSWORD: ${CI_REGISTRY_PASSWORD} # Docker registry password - ENABLE_INDUSTRIAL_CI: 'false' # Enable industrial_ci - ENABLE_SINGLEARCH_PUSH: 'false' # Enable push of single arch images with [-amd64|-arm64] postfix - PUSH_AS_LATEST: 'false' # Push image additionally with tag 'latest' + TARGET: run # Target stage of Dockerfile (comma-separated list) [dev|run] + PLATFORM: '' # Target platform architecture (comma-separated list) [amd64|arm64|...] + BASE_IMAGE: '' # Base image name:tag (required) + COMMAND: '' # Launch command of run image (required if target=run) + IMAGE_NAME: ${CI_REGISTRY_IMAGE} # Image name of run image + IMAGE_TAG: latest # Image tag of run image + DEV_IMAGE_NAME: ${IMAGE_NAME} # Image name of dev image + DEV_IMAGE_TAG: ${IMAGE_TAG}-dev # Image tag of dev image + BUILD_CONTEXT: . # Build context of Docker build process + REGISTRY: ${CI_REGISTRY} # Docker registry to push images to + REGISTRY_USERNAME: ${CI_REGISTRY_USER} # Docker registry username + REGISTRY_PASSWORD: ${CI_REGISTRY_PASSWORD} # Docker registry password + ENABLE_INDUSTRIAL_CI: 'false' # Enable industrial_ci + ENABLE_SINGLEARCH_PUSH: 'false' # Enable push of single arch images with [-amd64|-arm64] postfix + PUSH_AS_LATEST: 'false' # Push image additionally with tag 'latest' GIT_HTTPS_SERVER: ${CI_SERVER_HOST}:${CI_SERVER_PORT} # git server address for private repositories without protocol (e.g. github.com) GIT_HTTPS_USER: gitlab-ci-token # git https username for private repository access GIT_HTTPS_PASSWORD: ${CI_JOB_TOKEN} # git https password/token for private repository access - RUN_IMAGE: ${IMAGE_NAME}:${IMAGE_TAG} - DEV_IMAGE: ${DEV_IMAGE_NAME}:${DEV_IMAGE_TAG} + _RUN_IMAGE: ${IMAGE_NAME}:${IMAGE_TAG} + _DEV_IMAGE: ${DEV_IMAGE_NAME}:${DEV_IMAGE_TAG} - IMAGE_DEV_CI: ${DEV_IMAGE}_${CI_COMMIT_REF_SLUG}_ci - IMAGE_RUN_CI: ${RUN_IMAGE}_${CI_COMMIT_REF_SLUG}_ci - IMAGE_DEV_CI_AMD64: ${IMAGE_DEV_CI}-amd64 - IMAGE_DEV_CI_ARM64: ${IMAGE_DEV_CI}-arm64 - IMAGE_RUN_CI_AMD64: ${IMAGE_RUN_CI}-amd64 - IMAGE_RUN_CI_ARM64: ${IMAGE_RUN_CI}-arm64 - IMAGE_DEV_LATEST: ${DEV_IMAGE_NAME}:latest-dev - IMAGE_RUN_LATEST: ${IMAGE_NAME}:latest - IMAGE_DEV_TARGET_TAG: ${DEV_IMAGE}-${CI_COMMIT_TAG}-dev - IMAGE_RUN_TARGET_TAG: ${RUN_IMAGE}-${CI_COMMIT_TAG} - IMAGE_DEV_TAG: ${DEV_IMAGE_NAME}:${CI_COMMIT_TAG}-dev - IMAGE_RUN_TAG: ${IMAGE_NAME}:${CI_COMMIT_TAG} + _IMAGE_DEV_CI: ${_DEV_IMAGE}_${CI_COMMIT_REF_SLUG}_ci + _IMAGE_RUN_CI: ${_RUN_IMAGE}_${CI_COMMIT_REF_SLUG}_ci + _IMAGE_DEV_CI_AMD64: ${_IMAGE_DEV_CI}-amd64 + _IMAGE_DEV_CI_ARM64: ${_IMAGE_DEV_CI}-arm64 + _IMAGE_RUN_CI_AMD64: ${_IMAGE_RUN_CI}-amd64 + _IMAGE_RUN_CI_ARM64: ${_IMAGE_RUN_CI}-arm64 + _IMAGE_DEV_LATEST: ${DEV_IMAGE_NAME}:latest-dev + _IMAGE_RUN_LATEST: ${IMAGE_NAME}:latest + _IMAGE_DEV_TARGET_TAG: ${_DEV_IMAGE}-${CI_COMMIT_TAG} + _IMAGE_RUN_TARGET_TAG: ${_RUN_IMAGE}-${CI_COMMIT_TAG} + _IMAGE_DEV_TAG: ${DEV_IMAGE_NAME}:${CI_COMMIT_TAG}-dev + _IMAGE_RUN_TAG: ${IMAGE_NAME}:${CI_COMMIT_TAG} # ----- DOCKER_ROS_GIT_REF: main DISABLE_PUSH: 'false' @@ -100,7 +100,7 @@ dev-amd64: variables: PLATFORM: amd64 TARGET: dev - IMAGE: ${IMAGE_DEV_CI_AMD64} + IMAGE: ${_IMAGE_DEV_CI_AMD64} dev-arm64: stage: Build dev Images @@ -111,7 +111,7 @@ dev-arm64: variables: PLATFORM: arm64 TARGET: dev - IMAGE: ${IMAGE_DEV_CI_ARM64} + IMAGE: ${_IMAGE_DEV_CI_ARM64} run-amd64: stage: Build run Images @@ -125,7 +125,7 @@ run-amd64: PLATFORM: amd64 COMMAND: ${COMMAND} TARGET: run - IMAGE: ${IMAGE_RUN_CI_AMD64} + IMAGE: ${_IMAGE_RUN_CI_AMD64} run-arm64: stage: Build run Images @@ -140,7 +140,7 @@ run-arm64: PLATFORM: arm64 COMMAND: ${COMMAND} TARGET: run - IMAGE: ${IMAGE_RUN_CI_ARM64} + IMAGE: ${_IMAGE_RUN_CI_ARM64} .test: @@ -164,9 +164,9 @@ Test dev-amd64: - job: dev-amd64 optional: true rules: - - if: $ENABLE_INDUSTRIAL_CI == 'true' && ${PLATFORM} =~ 'amd64' + - if: ${ENABLE_INDUSTRIAL_CI} == 'true' && ${PLATFORM} =~ 'amd64' variables: - DOCKER_IMAGE: ${IMAGE_DEV_CI_AMD64} + DOCKER_IMAGE: ${_IMAGE_DEV_CI_AMD64} Test dev-arm64: stage: Test ROS Industrial CI @@ -176,9 +176,9 @@ Test dev-arm64: - job: dev-arm64 optional: true rules: - - if: $ENABLE_INDUSTRIAL_CI == 'true' && ${PLATFORM} =~ 'arm64' + - if: ${ENABLE_INDUSTRIAL_CI} == 'true' && ${PLATFORM} =~ 'arm64' variables: - DOCKER_IMAGE: ${IMAGE_DEV_CI_ARM64} + DOCKER_IMAGE: ${_IMAGE_DEV_CI_ARM64} .push: @@ -201,14 +201,14 @@ Test dev-arm64: script: - |- if [[ ${PLATFORM} =~ 'amd64' && ${PLATFORM} =~ 'arm64' ]]; then - [[ ${TARGET} =~ 'dev' ]] && docker manifest create ${IMG_DEV} --amend ${IMAGE_DEV_CI_AMD64} --amend ${IMAGE_DEV_CI_ARM64} - [[ ${TARGET} =~ 'run' ]] && docker manifest create ${IMG_RUN} --amend ${IMAGE_RUN_CI_AMD64} --amend ${IMAGE_RUN_CI_ARM64} + [[ ${TARGET} =~ 'dev' ]] && docker manifest create ${IMG_DEV} --amend ${_IMAGE_DEV_CI_AMD64} --amend ${_IMAGE_DEV_CI_ARM64} + [[ ${TARGET} =~ 'run' ]] && docker manifest create ${IMG_RUN} --amend ${_IMAGE_RUN_CI_AMD64} --amend ${_IMAGE_RUN_CI_ARM64} elif [[ ${PLATFORM} == 'amd64' ]]; then - [[ ${TARGET} =~ 'dev' ]] && docker manifest create ${IMG_DEV} --amend ${IMAGE_DEV_CI_AMD64} - [[ ${TARGET} =~ 'run' ]] && docker manifest create ${IMG_RUN} --amend ${IMAGE_RUN_CI_AMD64} + [[ ${TARGET} =~ 'dev' ]] && docker manifest create ${IMG_DEV} --amend ${_IMAGE_DEV_CI_AMD64} + [[ ${TARGET} =~ 'run' ]] && docker manifest create ${IMG_RUN} --amend ${_IMAGE_RUN_CI_AMD64} elif [[ ${PLATFORM} == 'amd64' ]]; then - [[ ${TARGET} =~ 'dev' ]] && docker manifest create ${IMG_DEV} --amend ${IMAGE_DEV_CI_ARM64} - [[ ${TARGET} =~ 'run' ]] && docker manifest create ${IMG_RUN} --amend ${IMAGE_RUN_CI_ARM64} + [[ ${TARGET} =~ 'dev' ]] && docker manifest create ${IMG_DEV} --amend ${_IMAGE_DEV_CI_ARM64} + [[ ${TARGET} =~ 'run' ]] && docker manifest create ${IMG_RUN} --amend ${_IMAGE_RUN_CI_ARM64} fi - |- [[ ${TARGET} =~ 'dev' ]] && docker manifest push ${IMG_DEV} @@ -223,8 +223,8 @@ Push CI: when: never - if: $CI_COMMIT_BRANCH != $CI_DEFAULT_BRANCH variables: - IMG_DEV: ${IMAGE_DEV_CI} - IMG_RUN: ${IMAGE_RUN_CI} + IMG_DEV: ${_IMAGE_DEV_CI} + IMG_RUN: ${_IMAGE_RUN_CI} Push: stage: Push Multi-Arch Images @@ -233,8 +233,8 @@ Push: - !reference [.push, rules] - if: $CI_COMMIT_BRANCH == $CI_DEFAULT_BRANCH variables: - IMG_DEV: ${IMAGE_DEV_TARGET} - IMG_RUN: ${IMAGE_RUN_TARGET} + IMG_DEV: ${_DEV_IMAGE} + IMG_RUN: ${_RUN_IMAGE} Push latest: stage: Push Multi-Arch Images @@ -243,8 +243,8 @@ Push latest: - !reference [.push, rules] - if: $CI_COMMIT_BRANCH == $CI_DEFAULT_BRANCH && $PUSH_AS_LATEST == 'true' variables: - IMG_DEV: ${IMAGE_DEV_LATEST} - IMG_RUN: ${IMAGE_RUN_LATEST} + IMG_DEV: ${_IMAGE_DEV_LATEST} + IMG_RUN: ${_IMAGE_RUN_LATEST} Push target tag: stage: Push Multi-Arch Images @@ -253,8 +253,8 @@ Push target tag: - !reference [.push, rules] - if: $CI_COMMIT_TAG variables: - IMG_DEV: ${IMAGE_DEV_TARGET_TAG} - IMG_RUN: ${IMAGE_RUN_TARGET_TAG} + IMG_DEV: ${_IMAGE_DEV_TARGET_TAG} + IMG_RUN: ${_IMAGE_RUN_TARGET_TAG} Push tag: stage: Push Multi-Arch Images @@ -263,5 +263,5 @@ Push tag: - !reference [.push, rules] - if: $CI_COMMIT_TAG && $PUSH_AS_LATEST == 'true' variables: - IMG_DEV: ${IMAGE_DEV_TAG} - IMG_RUN: ${IMAGE_RUN_TAG} + IMG_DEV: ${_IMAGE_DEV_TAG} + IMG_RUN: ${_IMAGE_RUN_TAG} From 94ab99a766ff9f156a57a2047a172ce7acaf402e Mon Sep 17 00:00:00 2001 From: Jean-Pierre Busch Date: Mon, 5 Jun 2023 15:25:55 +0200 Subject: [PATCH 116/159] remove DISABLE_PUSH --- templates/.gitlab-ci.template.yml | 7 +++---- 1 file changed, 3 insertions(+), 4 deletions(-) diff --git a/templates/.gitlab-ci.template.yml b/templates/.gitlab-ci.template.yml index 775ec4d..ba8ee86 100644 --- a/templates/.gitlab-ci.template.yml +++ b/templates/.gitlab-ci.template.yml @@ -27,6 +27,8 @@ variables: GIT_HTTPS_SERVER: ${CI_SERVER_HOST}:${CI_SERVER_PORT} # git server address for private repositories without protocol (e.g. github.com) GIT_HTTPS_USER: gitlab-ci-token # git https username for private repository access GIT_HTTPS_PASSWORD: ${CI_JOB_TOKEN} # git https password/token for private repository access + # ----- + DOCKER_ROS_GIT_REF: main _RUN_IMAGE: ${IMAGE_NAME}:${IMAGE_TAG} _DEV_IMAGE: ${DEV_IMAGE_NAME}:${DEV_IMAGE_TAG} @@ -43,10 +45,7 @@ variables: _IMAGE_RUN_TARGET_TAG: ${_RUN_IMAGE}-${CI_COMMIT_TAG} _IMAGE_DEV_TAG: ${DEV_IMAGE_NAME}:${CI_COMMIT_TAG}-dev _IMAGE_RUN_TAG: ${IMAGE_NAME}:${CI_COMMIT_TAG} - # ----- - DOCKER_ROS_GIT_REF: main - DISABLE_PUSH: 'false' - # ----- + GIT_SUBMODULE_STRATEGY: recursive DOCKER_DRIVER: overlay2 DOCKER_TLS_CERTDIR: /certs From 00ffe947674a10faa11ab2ff2944bfa842259ff0 Mon Sep 17 00:00:00 2001 From: Jean-Pierre Busch Date: Mon, 5 Jun 2023 15:55:28 +0200 Subject: [PATCH 117/159] gitlab-ci.yml - fix syntax --- templates/.gitlab-ci.template.yml | 14 +++++++------- 1 file changed, 7 insertions(+), 7 deletions(-) diff --git a/templates/.gitlab-ci.template.yml b/templates/.gitlab-ci.template.yml index ba8ee86..9c5dcf1 100644 --- a/templates/.gitlab-ci.template.yml +++ b/templates/.gitlab-ci.template.yml @@ -95,7 +95,7 @@ dev-amd64: stage: Build dev Images extends: .build rules: - - if: ${PLATFORM} =~ 'amd64' && ${TARGET} =~ 'dev' + - if: $PLATFORM =~ 'amd64' && $TARGET =~ 'dev' variables: PLATFORM: amd64 TARGET: dev @@ -106,7 +106,7 @@ dev-arm64: extends: .build tags: [privileged, arm64] rules: - - if: ${PLATFORM} =~ 'arm64' && ${TARGET} =~ 'dev' + - if: $PLATFORM =~ 'arm64' && $TARGET =~ 'dev' variables: PLATFORM: arm64 TARGET: dev @@ -119,7 +119,7 @@ run-amd64: - job: dev-amd64 optional: true rules: - - if: ${PLATFORM} =~ 'amd64' && ${TARGET} =~ 'run' + - if: $PLATFORM =~ 'amd64' && $TARGET =~ 'run' variables: PLATFORM: amd64 COMMAND: ${COMMAND} @@ -134,7 +134,7 @@ run-arm64: - job: dev-arm64 optional: true rules: - - if: ${PLATFORM} =~ 'arm64' && ${TARGET} =~ 'run' + - if: $PLATFORM =~ 'arm64' && $TARGET =~ 'run' variables: PLATFORM: arm64 COMMAND: ${COMMAND} @@ -163,7 +163,7 @@ Test dev-amd64: - job: dev-amd64 optional: true rules: - - if: ${ENABLE_INDUSTRIAL_CI} == 'true' && ${PLATFORM} =~ 'amd64' + - if: $ENABLE_INDUSTRIAL_CI == 'true' && $PLATFORM =~ 'amd64' variables: DOCKER_IMAGE: ${_IMAGE_DEV_CI_AMD64} @@ -175,7 +175,7 @@ Test dev-arm64: - job: dev-arm64 optional: true rules: - - if: ${ENABLE_INDUSTRIAL_CI} == 'true' && ${PLATFORM} =~ 'arm64' + - if: $ENABLE_INDUSTRIAL_CI == 'true' && $PLATFORM =~ 'arm64' variables: DOCKER_IMAGE: ${_IMAGE_DEV_CI_ARM64} @@ -195,7 +195,7 @@ Test dev-arm64: - job: Test dev-arm64 optional: true rules: - - if: ${PLATFORM} == '' || ${TARGET} == '' + - if: $PLATFORM == '' || $TARGET == '' when: never script: - |- From 2253f465fd0decabe673f53e9165dd674ac7fe96 Mon Sep 17 00:00:00 2001 From: Jean-Pierre Busch Date: Mon, 5 Jun 2023 16:20:32 +0200 Subject: [PATCH 118/159] use prefixed vars for build jobs --- templates/.gitlab-ci.template.yml | 22 ++++++++++++---------- 1 file changed, 12 insertions(+), 10 deletions(-) diff --git a/templates/.gitlab-ci.template.yml b/templates/.gitlab-ci.template.yml index 9c5dcf1..fdb1f88 100644 --- a/templates/.gitlab-ci.template.yml +++ b/templates/.gitlab-ci.template.yml @@ -67,7 +67,7 @@ default: - privileged - amd64 before_script: - - apk add bash + - apk add bash dpkg - cd ${BUILD_CONTEXT} - |- if [[ ! -d $docker/docker-ros ]]; then @@ -81,6 +81,8 @@ default: - |- if [[ $(dpkg --print-architecture) != ${PLATFORM} ]]; then docker run --rm --privileged multiarch/qemu-user-static --reset -p yes + dpkg --print-architecture + echo ${CI_RUNNER_EXECUTABLE_ARCH} fi - docker login -u ${REGISTRY_USERNAME} -p ${REGISTRY_PASSWORD} ${REGISTRY} - docker context create buildx-context @@ -88,7 +90,7 @@ default: .build: script: - - ./docker/docker-ros/scripts/build.sh + - PLATFORM=${BUILD_PLATFORM} TARGET=${BUILD_TARGET} ./docker/docker-ros/scripts/build.sh - docker push ${IMAGE} dev-amd64: @@ -97,8 +99,8 @@ dev-amd64: rules: - if: $PLATFORM =~ 'amd64' && $TARGET =~ 'dev' variables: - PLATFORM: amd64 - TARGET: dev + BUILD_PLATFORM: amd64 + BUILD_TARGET: dev IMAGE: ${_IMAGE_DEV_CI_AMD64} dev-arm64: @@ -108,8 +110,8 @@ dev-arm64: rules: - if: $PLATFORM =~ 'arm64' && $TARGET =~ 'dev' variables: - PLATFORM: arm64 - TARGET: dev + BUILD_PLATFORM: arm64 + BUILD_TARGET: dev IMAGE: ${_IMAGE_DEV_CI_ARM64} run-amd64: @@ -121,9 +123,9 @@ run-amd64: rules: - if: $PLATFORM =~ 'amd64' && $TARGET =~ 'run' variables: - PLATFORM: amd64 + BUILD_PLATFORM: amd64 COMMAND: ${COMMAND} - TARGET: run + BUILD_TARGET: run IMAGE: ${_IMAGE_RUN_CI_AMD64} run-arm64: @@ -136,9 +138,9 @@ run-arm64: rules: - if: $PLATFORM =~ 'arm64' && $TARGET =~ 'run' variables: - PLATFORM: arm64 + BUILD_PLATFORM: arm64 COMMAND: ${COMMAND} - TARGET: run + BUILD_TARGET: run IMAGE: ${_IMAGE_RUN_CI_ARM64} From ca7b6a2a8bf4e570259f74e4ad8720c414a98854 Mon Sep 17 00:00:00 2001 From: Jean-Pierre Busch Date: Mon, 5 Jun 2023 16:41:29 +0200 Subject: [PATCH 119/159] tag becomes image-tag --- action.yml | 12 ++++++------ scripts/ci.sh | 8 ++++---- 2 files changed, 10 insertions(+), 10 deletions(-) diff --git a/action.yml b/action.yml index b946a1c..67c6d34 100644 --- a/action.yml +++ b/action.yml @@ -21,14 +21,14 @@ inputs: description: "Image name of run image" default: ghcr.io/${{ github.repository }} - tag: + image-tag: description: "Image tag of run image" default: latest dev-image-name: description: "Image name of dev image" - dev-tag: + dev-image-tag: description: "Image tag of dev image" build-context: @@ -104,9 +104,9 @@ runs: BASE_IMAGE: ${{ inputs.base-image }} COMMAND: ${{ inputs.command }} IMAGE_NAME: ${{ inputs.image-name }} - TAG: ${{ inputs.tag }} + IMAGE_TAG: ${{ inputs.image-tag }} DEV_IMAGE_NAME: ${{ inputs.dev-image-name }} - DEV_TAG: ${{ inputs.dev-tag }} + DEV_IMAGE_TAG: ${{ inputs.dev-image-tag }} - name: Set up industrial_ci if: ${{ inputs.enable-industrial-ci == 'true' }} @@ -140,9 +140,9 @@ runs: BASE_IMAGE: ${{ inputs.base-image }} COMMAND: ${{ inputs.command }} IMAGE_NAME: ${{ inputs.image-name }} - TAG: ${{ inputs.tag }} + IMAGE_TAG: ${{ inputs.image-tag }} DEV_IMAGE_NAME: ${{ inputs.dev-image-name }} - DEV_TAG: ${{ inputs.dev-tag }} + DEV_IMAGE_TAG: ${{ inputs.dev-image-tag }} ENABLE_SINGLEARCH_PUSH: ${{ inputs.enable-singlearch-push }} _ENABLE_IMAGE_PUSH: true _IMAGE_POSTFIX: ${{ github.ref != format('refs/heads/{0}', github.event.repository.default_branch) && format('_{0}_ci', steps.slugify-ref-name.outputs.slug) || '' }} diff --git a/scripts/ci.sh b/scripts/ci.sh index 72c8c55..42b2a3f 100755 --- a/scripts/ci.sh +++ b/scripts/ci.sh @@ -12,13 +12,13 @@ TARGET="${TARGET:-run}" PLATFORM="${PLATFORM:-$(dpkg --print-architecture)}" require_var "BASE_IMAGE" require_var "IMAGE_NAME" -TAG="${TAG:-latest}" +IMAGE_TAG="${IMAGE_TAG:-latest}" [[ "${TARGET}" == *"run"* ]] && require_var "COMMAND" DEV_IMAGE_NAME="${DEV_IMAGE_NAME:-${IMAGE_NAME}}" -DEV_TAG="${DEV_TAG:-${TAG}-dev}" +DEV_IMAGE_TAG="${DEV_IMAGE_TAG:-${IMAGE_TAG}-dev}" -IMAGE="${IMAGE_NAME}:${TAG}" -DEV_IMAGE="${DEV_IMAGE_NAME}:${DEV_TAG}" +IMAGE="${IMAGE_NAME}:${IMAGE_TAG}" +DEV_IMAGE="${DEV_IMAGE_NAME}:${DEV_IMAGE_TAG}" ENABLE_SINGLEARCH_PUSH="${ENABLE_SINGLEARCH_PUSH:-false}" From 2d830ed120debaf4364611796d08d5699ccba95e Mon Sep 17 00:00:00 2001 From: Jean-Pierre Busch Date: Mon, 5 Jun 2023 16:54:14 +0200 Subject: [PATCH 120/159] start preparing ci.sh for gitlab-ci --- scripts/ci.sh | 6 +++--- scripts/utils.sh | 12 ++++++++++-- 2 files changed, 13 insertions(+), 5 deletions(-) diff --git a/scripts/ci.sh b/scripts/ci.sh index 42b2a3f..9ddf5c4 100755 --- a/scripts/ci.sh +++ b/scripts/ci.sh @@ -17,8 +17,8 @@ IMAGE_TAG="${IMAGE_TAG:-latest}" DEV_IMAGE_NAME="${DEV_IMAGE_NAME:-${IMAGE_NAME}}" DEV_IMAGE_TAG="${DEV_IMAGE_TAG:-${IMAGE_TAG}-dev}" -IMAGE="${IMAGE_NAME}:${IMAGE_TAG}" -DEV_IMAGE="${DEV_IMAGE_NAME}:${DEV_IMAGE_TAG}" +IMAGE="${IMAGE:-${IMAGE_NAME}:${IMAGE_TAG}}" +DEV_IMAGE="${DEV_IMAGE:-${DEV_IMAGE_NAME}:${DEV_IMAGE_TAG}}" ENABLE_SINGLEARCH_PUSH="${ENABLE_SINGLEARCH_PUSH:-false}" @@ -35,7 +35,7 @@ if [[ "${PLATFORM}" != *","* ]]; then else industrial_ci_image="${industrial_ci_image}-$(dpkg --print-architecture)" fi -echo "INDUSTRIAL_CI_IMAGE=${industrial_ci_image}" >> "${GITHUB_OUTPUT}" +[[ ! "${GITLAB_CI}" ]] && echo "INDUSTRIAL_CI_IMAGE=${industrial_ci_image}" >> "${GITHUB_OUTPUT}" # parse (potentially) comma-separated lists to arrays IFS="," read -ra TARGETS <<< "${TARGET}" diff --git a/scripts/utils.sh b/scripts/utils.sh index 31ad494..7120ceb 100644 --- a/scripts/utils.sh +++ b/scripts/utils.sh @@ -8,9 +8,17 @@ require_var() { } open_log_group() { - echo "::group::[docker-ros] ${1}" + if [[ "${GITLAB_CI}" ]]; then + echo "\e[0Ksection_start:`date +%s`:my_first_section\r\e[0K${1}" + elif [[ "${CI}" ]]; then + echo "::group::[docker-ros] ${1}" + fi } close_log_group() { - echo "::endgroup::" + if [[ "${GITLAB_CI}" ]]; then + echo -e "\e[0Ksection_end:`date +%s`:my_first_section\r\e[0K" + elif [[ "${CI}" ]]; then + echo "::endgroup::" + fi } From edde80da3d4cfdfc29f9c422f007484b1098f5c6 Mon Sep 17 00:00:00 2001 From: Jean-Pierre Busch Date: Mon, 5 Jun 2023 17:02:12 +0200 Subject: [PATCH 121/159] gitlab-ci.yml - use ci.sh instead of build.sh --- templates/.gitlab-ci.template.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/templates/.gitlab-ci.template.yml b/templates/.gitlab-ci.template.yml index fdb1f88..c25f192 100644 --- a/templates/.gitlab-ci.template.yml +++ b/templates/.gitlab-ci.template.yml @@ -90,7 +90,7 @@ default: .build: script: - - PLATFORM=${BUILD_PLATFORM} TARGET=${BUILD_TARGET} ./docker/docker-ros/scripts/build.sh + - PLATFORM=${BUILD_PLATFORM} TARGET=${BUILD_TARGET} ./docker/docker-ros/scripts/ci.sh - docker push ${IMAGE} dev-amd64: From bc6e19ef4c0e1c2846f162d9704d6a43b5e64d6d Mon Sep 17 00:00:00 2001 From: Lennart Reiher Date: Mon, 5 Jun 2023 23:14:01 +0200 Subject: [PATCH 122/159] pass build-args for git https/ssh config --- action.yml | 28 ++++++++++++++++++++++++++++ docker/Dockerfile | 8 +++----- scripts/build.sh | 6 ++++-- scripts/ci.sh | 8 +++++--- 4 files changed, 40 insertions(+), 10 deletions(-) diff --git a/action.yml b/action.yml index 67c6d34..ae042f4 100644 --- a/action.yml +++ b/action.yml @@ -46,6 +46,24 @@ inputs: registry-password: description: "Docker registry password" default: ${{ github.token }} + + git-https-server: + description: "Server URL (without protocol) for cloning private Git repositories via HTTPS" + default: "github.com" + + git-https-user: + description: "Username for cloning private Git repositories via HTTPS" + default: ${{ github.actor }} + + git-https-password: + description: "Password for cloning private Git repositories via HTTPS" + default: ${{ github.token }} + + git-ssh-private-key: + description: "SSH private key for cloning private Git repositories via SSH" + + git-ssh-known-host-keys: + description: "Known SSH host keys for cloning private Git repositories via SSH (may be obtained using `ssh-keyscan`)" enable-industrial-ci: description: "Enable industrial_ci" @@ -107,6 +125,11 @@ runs: IMAGE_TAG: ${{ inputs.image-tag }} DEV_IMAGE_NAME: ${{ inputs.dev-image-name }} DEV_IMAGE_TAG: ${{ inputs.dev-image-tag }} + GIT_HTTPS_SERVER: ${{ inputs.git-https-server }} + GIT_HTTPS_USER: ${{ inputs.git-https-user }} + GIT_HTTPS_PASSWORD: ${{ inputs.git-https-password }} + GIT_SSH_PRIVATE_KEY: ${{ inputs.git-ssh-private-key }} + GIT_SSH_KNOWN_HOST_KEYS: ${{ inputs.git-ssh-known-host-keys }} - name: Set up industrial_ci if: ${{ inputs.enable-industrial-ci == 'true' }} @@ -144,5 +167,10 @@ runs: DEV_IMAGE_NAME: ${{ inputs.dev-image-name }} DEV_IMAGE_TAG: ${{ inputs.dev-image-tag }} ENABLE_SINGLEARCH_PUSH: ${{ inputs.enable-singlearch-push }} + GIT_HTTPS_SERVER: ${{ inputs.git-https-server }} + GIT_HTTPS_USER: ${{ inputs.git-https-user }} + GIT_HTTPS_PASSWORD: ${{ inputs.git-https-password }} + GIT_SSH_PRIVATE_KEY: ${{ inputs.git-ssh-private-key }} + GIT_SSH_KNOWN_HOST_KEYS: ${{ inputs.git-ssh-known-host-keys }} _ENABLE_IMAGE_PUSH: true _IMAGE_POSTFIX: ${{ github.ref != format('refs/heads/{0}', github.event.repository.default_branch) && format('_{0}_ci', steps.slugify-ref-name.outputs.slug) || '' }} diff --git a/docker/Dockerfile b/docker/Dockerfile index 4858477..521040d 100644 --- a/docker/Dockerfile +++ b/docker/Dockerfile @@ -47,13 +47,11 @@ RUN shopt -s dotglob && \ rm -r src/repository # clone .repos upstream dependencies -# TODO: remove hard-coded git server -# TODO: pass build-args for git authentication -ARG GIT_HTTPS_URL=https://gitlab.ika.rwth-aachen.de +ARG GIT_HTTPS_SERVER= ARG GIT_HTTPS_USER= ARG GIT_HTTPS_PASSWORD= -RUN if [ -n ${GIT_HTTPS_USER} ]; then \ - git config --global url.https://${GIT_HTTPS_USER}:${GIT_HTTPS_PASSWORD}@gitlab.ika.rwth-aachen.de.insteadOf ${GIT_HTTPS_URL} ; \ +RUN if [ -n ${GIT_HTTPS_SERVER} ]; then \ + git config --global url.https://${GIT_HTTPS_USER}:${GIT_HTTPS_PASSWORD}@${GIT_HTTPS_SERVER}.insteadOf https://${GIT_HTTPS_SERVER} ; \ fi ARG GIT_SSH_PRIVATE_KEY= ARG GIT_SSH_KNOWN_HOST_KEYS= diff --git a/scripts/build.sh b/scripts/build.sh index a4eca35..1486b3d 100755 --- a/scripts/build.sh +++ b/scripts/build.sh @@ -17,11 +17,13 @@ build_image() { $(if [[ "${_ENABLE_IMAGE_PUSH}" == "true" ]]; then echo "--push"; else echo "--load"; fi) \ --build-arg BASE_IMAGE="${BASE_IMAGE}" \ --build-arg COMMAND="${COMMAND}" \ - --build-arg GIT_HTTPS_PASSWORD="${GIT_HTTPS_PASSWORD}" \ + --build-arg GIT_HTTPS_SERVER="${GIT_HTTPS_SERVER}" \ --build-arg GIT_HTTPS_USER="${GIT_HTTPS_USER}" \ + --build-arg GIT_HTTPS_PASSWORD="${GIT_HTTPS_PASSWORD}" \ + --build-arg GIT_SSH_PRIVATE_KEY="${GIT_SSH_PRIVATE_KEY}" \ + --build-arg GIT_SSH_KNOWN_HOST_KEYS="${GIT_SSH_KNOWN_HOST_KEYS}" \ . echo "Successfully built stage '${TARGET}' for platform '${PLATFORM}' as '${IMAGE}'" - # TODO: GIT_HTTPS } diff --git a/scripts/ci.sh b/scripts/ci.sh index 9ddf5c4..a748456 100755 --- a/scripts/ci.sh +++ b/scripts/ci.sh @@ -16,12 +16,14 @@ IMAGE_TAG="${IMAGE_TAG:-latest}" [[ "${TARGET}" == *"run"* ]] && require_var "COMMAND" DEV_IMAGE_NAME="${DEV_IMAGE_NAME:-${IMAGE_NAME}}" DEV_IMAGE_TAG="${DEV_IMAGE_TAG:-${IMAGE_TAG}-dev}" - IMAGE="${IMAGE:-${IMAGE_NAME}:${IMAGE_TAG}}" DEV_IMAGE="${DEV_IMAGE:-${DEV_IMAGE_NAME}:${DEV_IMAGE_TAG}}" - ENABLE_SINGLEARCH_PUSH="${ENABLE_SINGLEARCH_PUSH:-false}" - +GIT_HTTPS_SERVER="${GIT_HTTPS_SERVER:-''}" +GIT_HTTPS_USER="${GIT_HTTPS_USER:-''}" +GIT_HTTPS_PASSWORD="${GIT_HTTPS_PASSWORD:-''}" +GIT_SSH_PRIVATE_KEY="${GIT_SSH_PRIVATE_KEY:-''}" +GIT_SSH_KNOWN_HOST_KEYS="${GIT_SSH_KNOWN_HOST_KEYS:-''}" _ENABLE_IMAGE_PUSH="${_ENABLE_IMAGE_PUSH:-false}" _IMAGE_POSTFIX="${_IMAGE_POSTFIX:-""}" From 53304277d7d640e71ded47771ec990615444c704 Mon Sep 17 00:00:00 2001 From: Lennart Reiher Date: Mon, 5 Jun 2023 23:14:14 +0200 Subject: [PATCH 123/159] configure private repo access in industrial_ci --- action.yml | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/action.yml b/action.yml index ae042f4..6d2ef47 100644 --- a/action.yml +++ b/action.yml @@ -142,7 +142,10 @@ runs: env: UPSTREAM_WORKSPACE: ${{ inputs.build-context }}/.repos TARGET_WORKSPACE: ${{ inputs.build-context }} - ADDITIONAL_DEBS: git # TODO AFTER_INIT_EMBED: git config --global url.${CI_SERVER_PROTOCOL}://gitlab-ci-token:${CI_JOB_TOKEN}@${CI_SERVER_HOST}:${CI_SERVER_PORT}.insteadOf ${CI_SERVER_URL} + ADDITIONAL_DEBS: git + AFTER_INIT_EMBED: '[[ -n ${{ inputs.git-https-server }} ]] && git config --global url.https://${{ inputs.git-https-user }}:${{ inputs.git-https-password }}@${{ inputs.git-https-server }}.insteadOf https://${{ inputs.git-https-server }}' + SSH_PRIVATE_KEY: ${{ inputs.git-ssh-private-key }} + SSH_SERVER_HOSTKEYS: ${{ inputs.git-ssh-known-host-keys }} DOCKER_RUN_OPTS: -u root:root DOCKER_IMAGE: ${{ steps.build-images.outputs.INDUSTRIAL_CI_IMAGE }} DOCKER_PULL: false From d9d5ef3fd2976744cbcc52d0a4fb2f2ab1ce5c73 Mon Sep 17 00:00:00 2001 From: Lennart Reiher Date: Mon, 5 Jun 2023 23:21:46 +0200 Subject: [PATCH 124/159] remove leftover build action --- .github/actions/docker-build/action.yml | 24 ------------------------ 1 file changed, 24 deletions(-) delete mode 100644 .github/actions/docker-build/action.yml diff --git a/.github/actions/docker-build/action.yml b/.github/actions/docker-build/action.yml deleted file mode 100644 index bd471f0..0000000 --- a/.github/actions/docker-build/action.yml +++ /dev/null @@ -1,24 +0,0 @@ -name: 'Docker build' -description: 'Docker build action' - -# TODO: document somewhere? -# required envvars -# PLATFORM -# TARGET -# BASE_IMAGE -# IMAGE -# COMMAND -# ROS_DIR -# DOCKER_DIR - -runs: - using: "composite" - steps: - - - name: docker build - run: | - cd ${ROS_DIR} - echo "::group::DOCKER BUILD" - ${GITHUB_WORKSPACE}/${DOCKER_DIR}/docker-ros/build.sh - echo "::endgroup::" - shell: bash From 904c52bace773ef17d0d98094bd15a15ec3ec711 Mon Sep 17 00:00:00 2001 From: Lennart Reiher Date: Mon, 5 Jun 2023 23:25:33 +0200 Subject: [PATCH 125/159] checkout readme from main --- README.md | 137 ++++++------------------------------------------------ 1 file changed, 13 insertions(+), 124 deletions(-) diff --git a/README.md b/README.md index af95191..682de85 100644 --- a/README.md +++ b/README.md @@ -1,129 +1,18 @@ - +# *docker-ros* – Automated Containerization of ROS Applications -# docker-ros +

+ + + +

-*docker-ros* automatically builds development and deployment Docker images for your ROS-based repositories. +*docker-ros* automatically builds minimal container images of ROS applications. -## Features +We recommend to use *docker-ros* in combination with our other tools for Docker and ROS. +- [*docker-ros-ml-images*](https://github.com/ika-rwth-aachen/docker-ros-ml-images) provides machine learning-enabled ROS Docker images +- [*docker-run*](https://github.com/ika-rwth-aachen/docker-run) is a CLI tool for simplified interaction with Docker images -*docker-ros* provides a generic [Dockerfile](Dockerfile) that can be used to build development and deployment Docker images for arbitrary ROS packages or package stacks. It also provides a [GitLab CI configuration](templates/.gitlab-ci.template.yml) that automatically builds these Docker images. The development image contains all required dependencies and the source code of your ROS-based repository. The deployment image only contains dependencies and the compiled binaries created by building the ROS packages in the repository. -The Dockerfile performs the following steps to automatically build these images: -1. All dependency repositories that are defined in a `.repos` file anywhere in the repository are cloned using [vcstool](https://github.com/dirk-thomas/vcstool). -1. The ROS dependencies listed in each package's `package.xml` are installed by [rosdep](https://docs.ros.org/en/independent/api/rosdep/html/). -1. *(optional)* Additional dependencies from a special file `additional.apt-dependencies` are installed, if needed. -1. *(optional)* A special folder `files/` is copied into the images, if needed. -1. *(optional)* A special script `custom.sh` is executed to perform further arbitrary installation commands, if needed. -1. *(deployment)* All ROS packages are built using `catkin` (ROS) or `colcon` (ROS2). -1. *(deployment)* A custom launch command is configured to run on container start. - -## Integration - -1. Add a `docker` folder to your repository. - ```bash - # ros-repository/ - mkdir docker - ``` -2. Copy the template [`docker-compose.template.yml`](templates/docker-compose.template.yml) to your `docker` folder as `docker-compose.yml`. -3. Edit the copied `docker-compose.yml` to specify key information about the images built for your repository. Note that only the top section of the file requires changes. - - `x-base-image: &base-image` - - base image for the images to be built - - any Ubuntu-based image is supported - - it is suggested to choose the most minimal [of our custom ROS images](https://gitlab.ika.rwth-aachen.de/fb-fi/ops/docker-base#available-images) - - `x-dev-image: &dev-image` - - image name and tag of the development image to be built - - it is suggested to use `gitlab.ika.rwth-aachen.de:5050//:latest-dev` - - `x-run-image: &run-image` - - image name and tag of the deployment image to be built - - it is suggested to use `gitlab.ika.rwth-aachen.de:5050//:latest` - - `x-command: &command` - - default Dockerfile [`CMD`](https://docs.docker.com/engine/reference/builder/#cmd) command of the deployment image -4. Create a new `.gitlab-ci.yml` file on the top level of your repository with the following contents. It will automatically include the pre-defined [`.gitlab-ci.template.yml`](templates/.gitlab-ci.template.yml). - ```yaml - include: - - project: fb-fi/ops/docker-ros - ref: main - file: templates/.gitlab-ci.template.yml - ``` -5. Integrate the section *Usage of docker-ros Images* of the template [`README.template.md`](templates/README.template.md) into your repository's README. For a proper and consistent documentation, it also makes sense to completely rebuild your README based on the template. -6. In your GitLab project, go to *Settings / General / Visibility, project features, permissions* and enable the *Container registry* to store the automatically built Docker images. Then go to *Settings / Packages and registries / Edit cleanup rules* and configure an image cleanup rule to *Remove tags matching* `.*_ci-.*`. It also makes sense to reset the default *Keep the most recent* setting to nothing. -7. Push the changes to your repository to have the GitLab CI pipeline build the images automatically. -8. *(optional)* Build the images locally using [`docker compose`](https://docs.docker.com/compose/) from the `docker` folder. This requires having a local clone of the *docker-ros* repository in your `docker` folder. If you commit the submodule, note that the CI will work with the submodule's commit. - ```bash - # ros-repository/ - git submodule add <../RELATIVE/PATH/..>/ops/docker-ros.git docker/docker-ros - cd docker - docker compose build dev run - ``` - -### Advanced Integration - -#### System Dependencies (apt) - -If your ROS-based repository requires system dependencies that cannot be installed by specifying their [rosdep](https://docs.ros.org/en/independent/api/rosdep/html/) keys in a `package.xml`, you can use the special `additional.apt-dependencies` file. - -Create a file `additional.apt-dependencies` in your `docker` folder and list any other dependencies that need to be installed via apt. - -#### Custom Installation Script - -If your ROS-based repository requires to execute any other installation or pre-/post-installation steps, you can use the special `custom.sh` script. - -Create a script `custom.sh` in your `docker` folder that executes arbitrary commands as part of the image building process. - -#### Extra Image Files - -If you need to have additional files present in the deployment image, you can use the special `files` folder. These will be copied into the container before the custom installation script `custom.sh` is executed. - -Create a folder `files` in your `docker` folder and place any files or directories in it. The contents will be copied to `/docker-ros/files` in the image. - -#### Git Credentials when Building Images Locally - -As part of the image build process, all dependency repositories that are defined in a `.repos` file anywhere in the repository are cloned using [vcstool](https://github.com/dirk-thomas/vcstool). This might fail due to missing Git credentials. You can pass Git credentials to build process by creating a special `.env` file. - -Create a file `.env` in your `docker` folder and specify username and password. If using GitLab, do not use your personal access credentials, but rather [create a temporary access token](https://docs.gitlab.com/ee/user/profile/personal_access_tokens.html#create-a-personal-access-token). -``` -GIT_HTTPS_USER="" -GIT_HTTPS_PASSWORD="" -``` - -#### Fixed *docker-ros* version in CI - -By default, the latest *docker-ros* `main` commit is used when the images are built in CI (see [Integration](#integration) step 4). You can specify a different Git reference by modifying your `.gitlab-ci.yml`. - -```yaml -include: - - project: fb-fi/ops/docker-ros - ref: # docker-ros Git ref for CI template - file: templates/.gitlab-ci.template.yml - -variables: - DOCKER_ROS_GIT_REF: # docker-ros Git ref for Dockerfile etc. -``` - -#### GitLab CI Customization - -If needed, you can overwrite any of the [GitLab CI variables of the template CI configuration](https://gitlab.ika.rwth-aachen.de/fb-fi/ops/docker-ros/-/blob/main/.gitlab-ci.template.yml#L14) from your own `.gitlab-ci.yml`. - -You can for example disable the [ROS Industrial CI](https://github.com/ros-industrial/industrial_ci) stage with a variable. -```yaml -include: - - project: fb-fi/ops/docker-ros - ref: main - file: templates/.gitlab-ci.template.yml -variables: - DISABLE_INDUSTRIAL_CI: 'true' -``` - -| Variable | Description | Default | -| --- | --- | --- | -| `DISABLE_ARCH_AMD64` | toggle the build of amd64 images | `'false'` | -| `DISABLE_ARCH_ARM64` | toggle the build of arm64 images | `'false'` | -| `DISABLE_INDUSTRIAL_CI` | toggle the ROS Industrial CI test job | `'false'` | -| `DISABLE_PUSH` | toggle the push of built images | `'false'` -| `DOCKER_COMPOSE_FILE` | name of the docker compose build file | `docker-compose.yml` | -| `DOCKER_COMPOSE_DIR` | path to directory in repository that contains the build file `DOCKER_COMPOSE_FILE` | `docker` | -| `DOCKER_ROS_GIT_REF` | *docker-ros* Git reference to use; should match what is specified in `include/ref` in your `gitlab-ci.yml` | `main` | -| `IMAGE_DEV_TARGET` | dev image tag, must match the one defined in `DOCKER_COMPOSE_FILE` | `${CI_REGISTRY_IMAGE}:latest-dev` | -| `IMAGE_RUN_TARGET` | run image tag, must match the one defined in `DOCKER_COMPOSE_FILE` | `${CI_REGISTRY_IMAGE}:latest` | -| `PUSH_AS_LATEST` | push `latest` tag in addition to the tag defined in `DOCKER_COMPOSE_FILE` | `'false'` | -| `ROS_DIR` | path to directory in repository that contains ROS packages | `.` | +> **Note** +> *docker-ros* is part of our tooling suite released with our paper [*Enabling the Deployment of Any-Scale Robotic Applications in Microservice-Based Service-Oriented Architectures through Automated Containerization*](https://github.com/ika-rwth-aachen/dorotos). +> We are currently refining the repository and the README for publication. If you, as a reviewer, would like to already try out *docker-ros*, please do not hesitate to contact us directly to get more detailed instructions. A more detailed README will also go online within the next few days. From 0b7ef08c06bf8250d1fecbd11d1cc9c2c93e187d Mon Sep 17 00:00:00 2001 From: Lennart Reiher Date: Tue, 6 Jun 2023 00:32:46 +0200 Subject: [PATCH 126/159] add usage examples and variables to readme --- README.md | 203 +++++++++++++++++++++++++++++++++++++++++++++++++++-- action.yml | 2 +- 2 files changed, 200 insertions(+), 5 deletions(-) diff --git a/README.md b/README.md index 682de85..938c4a9 100644 --- a/README.md +++ b/README.md @@ -3,16 +3,211 @@

-

*docker-ros* automatically builds minimal container images of ROS applications. +- [Usage](#usage) + - [Build a minimal image for deployment](#build-a-minimal-image-for-deployment) + - [Build development and deployment images](#build-development-and-deployment-images) + - [Build multi-arch images](#build-multi-arch-images) + - [Build deployment image with additional industrial\_ci check](#build-deployment-image-with-additional-industrial_ci-check) +- [Configuration Variables](#configuration-variables) + We recommend to use *docker-ros* in combination with our other tools for Docker and ROS. - [*docker-ros-ml-images*](https://github.com/ika-rwth-aachen/docker-ros-ml-images) provides machine learning-enabled ROS Docker images - [*docker-run*](https://github.com/ika-rwth-aachen/docker-run) is a CLI tool for simplified interaction with Docker images -> **Note** -> *docker-ros* is part of our tooling suite released with our paper [*Enabling the Deployment of Any-Scale Robotic Applications in Microservice-Based Service-Oriented Architectures through Automated Containerization*](https://github.com/ika-rwth-aachen/dorotos). -> We are currently refining the repository and the README for publication. If you, as a reviewer, would like to already try out *docker-ros*, please do not hesitate to contact us directly to get more detailed instructions. A more detailed README will also go online within the next few days. +## About + +... + + +## Usage + +### Build a minimal image for deployment + +
GitHub + +```yml +jobs: + docker-ros: + runs-on: ubuntu-latest + steps: + - uses: ika-rwth-aachen/docker-ros@main + with: + base-image: rwthika/ros2:humble + command: ros2 run my_pkg my_node +``` + +
+ +
GitLab + +```yml +include: + - remote: https://raw.githubusercontent.com/ika-rwth-aachen/docker-ros/main/templates/.gitlab-ci.template.yml + +variables: + BASE_IMAGE: rwthika/ros2:humble + COMMAND: ros2 run my_pkg my_node +``` + +
+ +### Build development and deployment images + +
GitHub + +```yml +jobs: + docker-ros: + runs-on: ubuntu-latest + steps: + - uses: ika-rwth-aachen/docker-ros@main + with: + base-image: rwthika/ros2:humble + command: ros2 run my_pkg my_node + target: dev,run +``` + +
+ +
GitLab + +```yml +include: + - remote: https://raw.githubusercontent.com/ika-rwth-aachen/docker-ros/main/templates/.gitlab-ci.template.yml + +variables: + BASE_IMAGE: rwthika/ros2:humble + COMMAND: ros2 run my_pkg my_node + TARGET: dev,run +``` + +
+ +### Build multi-arch images + +
GitHub + +```yml +jobs: + docker-ros: + runs-on: ubuntu-latest + steps: + - uses: ika-rwth-aachen/docker-ros@main + with: + base-image: rwthika/ros2:humble + command: ros2 run my_pkg my_node + target: dev,run + platform: amd64,arm64 +``` + +
+ +
GitLab + +```yml +include: + - remote: https://raw.githubusercontent.com/ika-rwth-aachen/docker-ros/main/templates/.gitlab-ci.template.yml + +variables: + BASE_IMAGE: rwthika/ros2:humble + COMMAND: ros2 run my_pkg my_node + TARGET: dev,run + PLATFORM: amd64,arm64 +``` + +
+ +### Build deployment image with additional industrial_ci check + +
GitHub + +```yml +jobs: + docker-ros: + runs-on: ubuntu-latest + steps: + - uses: ika-rwth-aachen/docker-ros@main + with: + base-image: rwthika/ros2:humble + command: ros2 run my_pkg my_node + enable-industrial-ci: 'true' +``` + +
+ +
GitLab + +```yml +include: + - remote: https://raw.githubusercontent.com/ika-rwth-aachen/docker-ros/main/templates/.gitlab-ci.template.yml + +variables: + BASE_IMAGE: rwthika/ros2:humble + COMMAND: ros2 run my_pkg my_node + ENABLE_INDUSTRIAL_CI: 'true' +``` + +
+ +### Build multi-arch images on arch-specific self-hosted runners in parallel + +
GitHub + +```yml +jobs: + docker-ros: + strategy: + matrix: + target: [dev, run] + platform: [amd64, arm64] + runs-on: [self-hosted, "${{ matrix.platform }}"] + steps: + - uses: ika-rwth-aachen/docker-ros@main + with: + base-image: rwthika/ros2:humble + command: ros2 run my_pkg my_node + target: ${{ matrix.target }} + platform: ${{ matrix.platform }} + enable-singlearch-push: true + # TODO: manifest +``` + +
+ +
GitLab + +```yml +# TODO +``` + +
+ +## Configuration Variables + +| GitHub Input | GitLab Env Var | Required | Description | Default GitHub | Default GitLab | Allow. Values | +| --- | --- | :---: | --- | :---: | :---: | :---: | +| `base_image` | `BASE_IMAGE` | x | Base image `name:tag` | - | - | - | +| `build-context` | `BUILD_CONTEXT` | - | Build context of Docker build process | `${{ github.workspace }}` | `.` | - | +| `command` | `COMMAND` | - | Launch command of run image (required if `target=run`) | - | - | - | +| `dev-image-name` | `DEV_IMAGE_NAME` | - | Image name of dev image | | | - | +| `dev-image-tag` | `DEV_IMAGE_TAG` | - | Image tag of dev image | `` | `"-dev` | - | +| - | `DOCKER_ROS_GIT_REF` | - | Git reference of *docker-ros* to run in CI | - | `main` | - | +| `enable-industrial-ci` | `ENABLE_INDUSTRIAL_CI` | - | Enable industrial_ci | `false` | `false` | `true`, `false` | +| `enable-singlearch-push` | `ENABLE_SINGLEARCH_PUSH` | - | Enable push of single arch images with `-amd64`/`-arm64` postfix | `false` | `false` | `true`, `false` | +| `git-https-password` | `GIT_HTTPS_PASSWORD` | - | Password for cloning private Git repositories via HTTPS | `${{ github.token }}` | `$CI_JOB_TOKEN` | - | +| `git-https-server` | `GIT_HTTPS_SERVER` | - | Server URL (without protocol) for cloning private Git repositories via HTTPS | `github.com` | `$CI_SERVER_HOST:$CI_SERVER_PORT` | - | +| `git-https-user` | `GIT_HTTPS_USER` | - | Username for cloning private Git repositories via HTTPS | `${{ github.actor }}` | `gitlab-ci-token` | | +| `git-ssh-known-host-keys` | `GIT_SSH_KNOWN_HOST_KEYS` | - | Known SSH host keys for cloning private Git repositories via SSH (may be obtained using `ssh-keyscan`) | - | - | - | +| `git-ssh-private-key` | `GIT_SSH_PRIVATE_KEY` | - | SSH private key for cloning private Git repositories via SSH | - | - | - | +| `image-name` | `IMAGE_NAME` | - | Image name of run image | `ghcr.io/${{ github.repository }}` | `$CI_REGISTRY_IMAGE` | - | +| `image-tag` | `IMAGE_TAG` | - | Image tag of run image | `latest` | `latest` | - | +| `platform` | `PLATFORM` | - | Target platform architecture (comma-separated list) | runner architecture | runner architecture | `amd64`, `arm64` | +| `registry-password` | `REGISTRY_PASSWORD` | - | Docker registry password | `${{ github.token }}` | `$CI_REGISTRY_PASSWORD` | - | +| `registry-username` | `REGISTRY_USERNAME` | - | Docker registry username | `${{ github.actor }}` | `$CI_REGISTRY_USER` | - | +| `registry` | `REGISTRY` | - | Docker registry to push images to | `ghcr.io` | `$CI_REGISTRY` | - | +| `target` | `TARGET` | - | Target stage of Dockerfile (comma-separated list) | `run` | `run` | `dev`, `run`, `dev,run` | diff --git a/action.yml b/action.yml index 6d2ef47..c0e2859 100644 --- a/action.yml +++ b/action.yml @@ -39,7 +39,7 @@ inputs: description: "Docker registry to push images to" default: ghcr.io - registry-username: + registry-username: # TODO: rename to user or rename git-https-username to user description: "Docker registry username" default: ${{ github.actor }} From e971dacf41f4c9f77a37e1a635a813ffed5e0040 Mon Sep 17 00:00:00 2001 From: Jean-Pierre Busch Date: Tue, 6 Jun 2023 00:45:18 +0200 Subject: [PATCH 127/159] revert adjustments in ci.sh for gitlab --- scripts/ci.sh | 5 +++-- scripts/utils.sh | 4 ++-- 2 files changed, 5 insertions(+), 4 deletions(-) diff --git a/scripts/ci.sh b/scripts/ci.sh index a748456..f9dad06 100755 --- a/scripts/ci.sh +++ b/scripts/ci.sh @@ -16,8 +16,9 @@ IMAGE_TAG="${IMAGE_TAG:-latest}" [[ "${TARGET}" == *"run"* ]] && require_var "COMMAND" DEV_IMAGE_NAME="${DEV_IMAGE_NAME:-${IMAGE_NAME}}" DEV_IMAGE_TAG="${DEV_IMAGE_TAG:-${IMAGE_TAG}-dev}" -IMAGE="${IMAGE:-${IMAGE_NAME}:${IMAGE_TAG}}" -DEV_IMAGE="${DEV_IMAGE:-${DEV_IMAGE_NAME}:${DEV_IMAGE_TAG}}" + +IMAGE="${IMAGE_NAME}:${IMAGE_TAG}" +DEV_IMAGE="${DEV_IMAGE_NAME}:${DEV_IMAGE_TAG}" ENABLE_SINGLEARCH_PUSH="${ENABLE_SINGLEARCH_PUSH:-false}" GIT_HTTPS_SERVER="${GIT_HTTPS_SERVER:-''}" GIT_HTTPS_USER="${GIT_HTTPS_USER:-''}" diff --git a/scripts/utils.sh b/scripts/utils.sh index 7120ceb..b8a9d99 100644 --- a/scripts/utils.sh +++ b/scripts/utils.sh @@ -9,7 +9,7 @@ require_var() { open_log_group() { if [[ "${GITLAB_CI}" ]]; then - echo "\e[0Ksection_start:`date +%s`:my_first_section\r\e[0K${1}" + echo "section_start:build_jobs:$(date +%s)" elif [[ "${CI}" ]]; then echo "::group::[docker-ros] ${1}" fi @@ -17,7 +17,7 @@ open_log_group() { close_log_group() { if [[ "${GITLAB_CI}" ]]; then - echo -e "\e[0Ksection_end:`date +%s`:my_first_section\r\e[0K" + echo "section_end:build_jobs:$(date +%s)" elif [[ "${CI}" ]]; then echo "::endgroup::" fi From 219d5926c157ebef4208c7ba93bd599378e1d6d7 Mon Sep 17 00:00:00 2001 From: Jean-Pierre Busch Date: Tue, 6 Jun 2023 00:56:18 +0200 Subject: [PATCH 128/159] add gitlab docker-ros-ci --- .github/workflows/gitlab.yml | 84 ++++++++++++++++++++++++++++++++++++ .github/workflows/main.yml | 2 +- 2 files changed, 85 insertions(+), 1 deletion(-) create mode 100644 .github/workflows/gitlab.yml diff --git a/.github/workflows/gitlab.yml b/.github/workflows/gitlab.yml new file mode 100644 index 0000000..ffafce3 --- /dev/null +++ b/.github/workflows/gitlab.yml @@ -0,0 +1,84 @@ +on: [push] + +jobs: + trigger-ros1: + name: Trigger ROS1 + runs-on: ubuntu-latest + steps: + - name: Checkout repository + uses: actions/checkout@v2 + + - name: Create artifacts directory + run: mkdir artifacts + + - name: Trigger pipeline + run: | + export PIPELINE_ID=$(curl --silent --fail --request POST \ + --header "PRIVATE-TOKEN: ${{ secrets.DOCKER_ROS_CI_GITLAB_PAT }}" \ + --form ref=main \ + --form "variables[DOCKER_ROS_GIT_REF]=$(git rev-parse HEAD)" \ + "https://gitlab.ika.rwth-aachen.de/api/v4/projects/1886/trigger/pipeline" \ + | jq -r .id) + echo $PIPELINE_ID > artifacts/id + + trigger-ros2: + name: Trigger ROS2 + runs-on: ubuntu-latest + steps: + - name: Checkout repository + uses: actions/checkout@v2 + + - name: Create artifacts directory + run: mkdir artifacts + + - name: Trigger pipeline + run: | + export PIPELINE_ID=$(curl --silent --fail --request POST \ + --header "PRIVATE-TOKEN: ${{ secrets.DOCKER_ROS_CI_GITLAB_PAT }}" \ + --form ref=ros2 \ + --form "variables[DOCKER_ROS_GIT_REF]=$(git rev-parse HEAD)" \ + "https://gitlab.ika.rwth-aachen.de/api/v4/projects/1886/trigger/pipeline" \ + | jq -r .id) + echo $PIPELINE_ID > artifacts/id + + watch-ros1: + name: Watch ROS1 + runs-on: ubuntu-latest + needs: trigger-ros1 + steps: + - name: Wait for pipeline completion + run: | + export PIPELINE_ID=$(cat artifacts/id) + while true; do + sleep 30 + export PIPELINE_STATUS=$(curl --silent --header "PRIVATE-TOKEN: ${{ secrets.DOCKER_ROS_CI_GITLAB_PAT }}" \ + "https://gitlab.ika.rwth-aachen.de/api/v4/projects/1886/pipelines/$PIPELINE_ID" \ + | jq -r .status) + echo "Pipeline status: $PIPELINE_STATUS (https://gitlab.ika.rwth-aachen.de/fb-fi/ops/docker-ros-ci/-/pipelines/$PIPELINE_ID)" + if [[ $PIPELINE_STATUS == "success" ]]; then + break + elif [[ $PIPELINE_STATUS == "failed" ]] || [[ $PIPELINE_STATUS == "canceled" ]]; then + exit 1 + fi + done + + watch-ros2: + name: Watch ROS2 + runs-on: ubuntu-latest + needs: trigger-ros2 + steps: + - name: Wait for pipeline completion + run: | + export PIPELINE_ID=$(cat artifacts/id) + while true; do + sleep 30 + export PIPELINE_STATUS=$(curl --silent --header "PRIVATE-TOKEN: ${{ secrets.DOCKER_ROS_CI_GITLAB_PAT }}" \ + "https://gitlab.ika.rwth-aachen.de/api/v4/projects/1886/pipelines/$PIPELINE_ID" \ + | jq -r .status) + echo "Pipeline status: $PIPELINE_STATUS (https://gitlab.ika.rwth-aachen.de/fb-fi/ops/docker-ros-ci/-/pipelines/$PIPELINE_ID)" + if [[ $PIPELINE_STATUS == "success" ]]; then + break + elif [[ $PIPELINE_STATUS == "failed" ]] || [[ $PIPELINE_STATUS == "canceled" ]]; then + exit 1 + fi + done \ No newline at end of file diff --git a/.github/workflows/main.yml b/.github/workflows/main.yml index aa2421a..8e13a6a 100644 --- a/.github/workflows/main.yml +++ b/.github/workflows/main.yml @@ -1,4 +1,4 @@ -on: [pull_request] +on: [push] jobs: trigger-docker-ros-ci-ros1: From 99a25c5343aebc2ab380ec424ce48767b1cbceed Mon Sep 17 00:00:00 2001 From: Jean-Pierre Busch <110477057+jpbusch@users.noreply.github.com> Date: Tue, 6 Jun 2023 01:11:27 +0200 Subject: [PATCH 129/159] gitlab - change title of collapsable section --- scripts/utils.sh | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/scripts/utils.sh b/scripts/utils.sh index b8a9d99..539f2e6 100644 --- a/scripts/utils.sh +++ b/scripts/utils.sh @@ -9,7 +9,7 @@ require_var() { open_log_group() { if [[ "${GITLAB_CI}" ]]; then - echo "section_start:build_jobs:$(date +%s)" + echo "section_start:`date +%s`:my_first_section[collapsed=true]\r\e[0K${1}" elif [[ "${CI}" ]]; then echo "::group::[docker-ros] ${1}" fi @@ -17,7 +17,7 @@ open_log_group() { close_log_group() { if [[ "${GITLAB_CI}" ]]; then - echo "section_end:build_jobs:$(date +%s)" + echo "section_end:`date +%s`:my_first_section\r\e[0K" elif [[ "${CI}" ]]; then echo "::endgroup::" fi From d5fbcc41d3bb0eefdcb14e0df768bbc8918f3b11 Mon Sep 17 00:00:00 2001 From: Jean-Pierre Busch Date: Tue, 6 Jun 2023 12:46:07 +0200 Subject: [PATCH 130/159] add push-as-latest input --- .github/workflows/gitlab.yml | 8 ++++---- action.yml | 27 +++++++++++++++++++++++++++ scripts/utils.sh | 4 ++-- 3 files changed, 33 insertions(+), 6 deletions(-) diff --git a/.github/workflows/gitlab.yml b/.github/workflows/gitlab.yml index ffafce3..18c136e 100644 --- a/.github/workflows/gitlab.yml +++ b/.github/workflows/gitlab.yml @@ -14,7 +14,7 @@ jobs: - name: Trigger pipeline run: | export PIPELINE_ID=$(curl --silent --fail --request POST \ - --header "PRIVATE-TOKEN: ${{ secrets.DOCKER_ROS_CI_GITLAB_PAT }}" \ + --header "PRIVATE-TOKEN: ${{ secrets.DOCKER_ROS_CI_TRIGGER_GITLAB_TOKEN }}" \ --form ref=main \ --form "variables[DOCKER_ROS_GIT_REF]=$(git rev-parse HEAD)" \ "https://gitlab.ika.rwth-aachen.de/api/v4/projects/1886/trigger/pipeline" \ @@ -34,7 +34,7 @@ jobs: - name: Trigger pipeline run: | export PIPELINE_ID=$(curl --silent --fail --request POST \ - --header "PRIVATE-TOKEN: ${{ secrets.DOCKER_ROS_CI_GITLAB_PAT }}" \ + --header "PRIVATE-TOKEN: ${{ secrets.DOCKER_ROS_CI_TRIGGER_GITLAB_TOKEN }}" \ --form ref=ros2 \ --form "variables[DOCKER_ROS_GIT_REF]=$(git rev-parse HEAD)" \ "https://gitlab.ika.rwth-aachen.de/api/v4/projects/1886/trigger/pipeline" \ @@ -51,7 +51,7 @@ jobs: export PIPELINE_ID=$(cat artifacts/id) while true; do sleep 30 - export PIPELINE_STATUS=$(curl --silent --header "PRIVATE-TOKEN: ${{ secrets.DOCKER_ROS_CI_GITLAB_PAT }}" \ + export PIPELINE_STATUS=$(curl --silent --header "PRIVATE-TOKEN: ${{ secrets.DOCKER_ROS_CI_READ_PIPELINE_GITLAB_TOKEN }}" \ "https://gitlab.ika.rwth-aachen.de/api/v4/projects/1886/pipelines/$PIPELINE_ID" \ | jq -r .status) echo "Pipeline status: $PIPELINE_STATUS (https://gitlab.ika.rwth-aachen.de/fb-fi/ops/docker-ros-ci/-/pipelines/$PIPELINE_ID)" @@ -72,7 +72,7 @@ jobs: export PIPELINE_ID=$(cat artifacts/id) while true; do sleep 30 - export PIPELINE_STATUS=$(curl --silent --header "PRIVATE-TOKEN: ${{ secrets.DOCKER_ROS_CI_GITLAB_PAT }}" \ + export PIPELINE_STATUS=$(curl --silent --header "PRIVATE-TOKEN: ${{ secrets.DOCKER_ROS_CI_READ_PIPELINE_GITLAB_TOKEN }}" \ "https://gitlab.ika.rwth-aachen.de/api/v4/projects/1886/pipelines/$PIPELINE_ID" \ | jq -r .status) echo "Pipeline status: $PIPELINE_STATUS (https://gitlab.ika.rwth-aachen.de/fb-fi/ops/docker-ros-ci/-/pipelines/$PIPELINE_ID)" diff --git a/action.yml b/action.yml index c0e2859..4df63d5 100644 --- a/action.yml +++ b/action.yml @@ -72,6 +72,10 @@ inputs: enable-singlearch-push: description: "Enable push of single arch images with [-amd64|-arm64] postfix" default: false + + push-as-latest: + description: "Push image additionaly with "latest" tag" + default: false runs: using: "composite" @@ -177,3 +181,26 @@ runs: GIT_SSH_KNOWN_HOST_KEYS: ${{ inputs.git-ssh-known-host-keys }} _ENABLE_IMAGE_PUSH: true _IMAGE_POSTFIX: ${{ github.ref != format('refs/heads/{0}', github.event.repository.default_branch) && format('_{0}_ci', steps.slugify-ref-name.outputs.slug) || '' }} + + - name: Push images (as latest) + if: ${{ inputs.push-as-latest == 'true' }} + shell: bash + working-directory: ${{ inputs.build-context }} + run: docker/docker-ros/scripts/ci.sh + env: + PLATFORM: ${{ inputs.platform }} + TARGET: ${{ inputs.target }} + BASE_IMAGE: ${{ inputs.base-image }} + COMMAND: ${{ inputs.command }} + IMAGE_NAME: ${{ inputs.image-name }} + IMAGE_TAG: latest + DEV_IMAGE_NAME: ${{ inputs.dev-image-name }} + DEV_IMAGE_TAG: latest-dev + ENABLE_SINGLEARCH_PUSH: ${{ inputs.enable-singlearch-push }} + GIT_HTTPS_SERVER: ${{ inputs.git-https-server }} + GIT_HTTPS_USER: ${{ inputs.git-https-user }} + GIT_HTTPS_PASSWORD: ${{ inputs.git-https-password }} + GIT_SSH_PRIVATE_KEY: ${{ inputs.git-ssh-private-key }} + GIT_SSH_KNOWN_HOST_KEYS: ${{ inputs.git-ssh-known-host-keys }} + _ENABLE_IMAGE_PUSH: true + _IMAGE_POSTFIX: ${{ github.ref != format('refs/heads/{0}', github.event.repository.default_branch) && format('_{0}_ci', steps.slugify-ref-name.outputs.slug) || '' }} \ No newline at end of file diff --git a/scripts/utils.sh b/scripts/utils.sh index 539f2e6..0caa07b 100644 --- a/scripts/utils.sh +++ b/scripts/utils.sh @@ -9,7 +9,7 @@ require_var() { open_log_group() { if [[ "${GITLAB_CI}" ]]; then - echo "section_start:`date +%s`:my_first_section[collapsed=true]\r\e[0K${1}" + echo -e "section_start:`date +%s`:my_first_section[collapsed=true]\r\e[0K${1}" elif [[ "${CI}" ]]; then echo "::group::[docker-ros] ${1}" fi @@ -17,7 +17,7 @@ open_log_group() { close_log_group() { if [[ "${GITLAB_CI}" ]]; then - echo "section_end:`date +%s`:my_first_section\r\e[0K" + echo -e "section_end:`date +%s`:my_first_section\r\e[0K" elif [[ "${CI}" ]]; then echo "::endgroup::" fi From 0e68c42ff41fc0d9382d368cb4dfcb15d5b7f05e Mon Sep 17 00:00:00 2001 From: Lennart Reiher Date: Tue, 6 Jun 2023 17:42:51 +0200 Subject: [PATCH 131/159] fix typo in inputs description --- action.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/action.yml b/action.yml index 4df63d5..a820406 100644 --- a/action.yml +++ b/action.yml @@ -74,7 +74,7 @@ inputs: default: false push-as-latest: - description: "Push image additionaly with "latest" tag" + description: "Push image additionaly with 'latest' tag" default: false runs: From 0aae4e3e604a1d8de6350f81188541e1dd4fac0f Mon Sep 17 00:00:00 2001 From: Lennart Reiher Date: Tue, 6 Jun 2023 18:22:26 +0200 Subject: [PATCH 132/159] fix trigger of gitlab docker-ros-ci --- .github/workflows/gitlab.yml | 75 +++++++----------------------------- 1 file changed, 14 insertions(+), 61 deletions(-) diff --git a/.github/workflows/gitlab.yml b/.github/workflows/gitlab.yml index 18c136e..58a1a5b 100644 --- a/.github/workflows/gitlab.yml +++ b/.github/workflows/gitlab.yml @@ -1,84 +1,37 @@ +name: GitLab + on: [push] jobs: - trigger-ros1: - name: Trigger ROS1 - runs-on: ubuntu-latest - steps: - - name: Checkout repository - uses: actions/checkout@v2 - - - name: Create artifacts directory - run: mkdir artifacts - - - name: Trigger pipeline - run: | - export PIPELINE_ID=$(curl --silent --fail --request POST \ - --header "PRIVATE-TOKEN: ${{ secrets.DOCKER_ROS_CI_TRIGGER_GITLAB_TOKEN }}" \ - --form ref=main \ - --form "variables[DOCKER_ROS_GIT_REF]=$(git rev-parse HEAD)" \ - "https://gitlab.ika.rwth-aachen.de/api/v4/projects/1886/trigger/pipeline" \ - | jq -r .id) - echo $PIPELINE_ID > artifacts/id - trigger-ros2: - name: Trigger ROS2 + trigger: + name: trigger runs-on: ubuntu-latest steps: - name: Checkout repository uses: actions/checkout@v2 - - - name: Create artifacts directory - run: mkdir artifacts - - name: Trigger pipeline run: | - export PIPELINE_ID=$(curl --silent --fail --request POST \ - --header "PRIVATE-TOKEN: ${{ secrets.DOCKER_ROS_CI_TRIGGER_GITLAB_TOKEN }}" \ - --form ref=ros2 \ - --form "variables[DOCKER_ROS_GIT_REF]=$(git rev-parse HEAD)" \ - "https://gitlab.ika.rwth-aachen.de/api/v4/projects/1886/trigger/pipeline" \ - | jq -r .id) - echo $PIPELINE_ID > artifacts/id + mkdir artifacts + curl --silent --fail --request POST --form "token=${{ secrets.DOCKER_ROS_CI_TRIGGER_GITLAB_TOKEN }}" --form "ref=main" --form "variables[DOCKER_ROS_GIT_REF]=$(git rev-parse HEAD)" "https://gitlab.ika.rwth-aachen.de/api/v4/projects/1886/trigger/pipeline" | jq -r .id > artifacts/id - watch-ros1: - name: Watch ROS1 + watch: + name: watch runs-on: ubuntu-latest - needs: trigger-ros1 + needs: trigger steps: - name: Wait for pipeline completion run: | - export PIPELINE_ID=$(cat artifacts/id) + PIPELINE_ID=$(cat artifacts/id) while true; do sleep 30 - export PIPELINE_STATUS=$(curl --silent --header "PRIVATE-TOKEN: ${{ secrets.DOCKER_ROS_CI_READ_PIPELINE_GITLAB_TOKEN }}" \ - "https://gitlab.ika.rwth-aachen.de/api/v4/projects/1886/pipelines/$PIPELINE_ID" \ - | jq -r .status) + PIPELINE_STATUS=$(curl --silent --header "PRIVATE-TOKEN: ${{ secrets.DOCKER_ROS_CI_READ_PIPELINE_GITLAB_TOKEN }}" "https://gitlab.ika.rwth-aachen.de/api/v4/projects/1886/pipelines/$PIPELINE_ID" | jq -r .status) echo "Pipeline status: $PIPELINE_STATUS (https://gitlab.ika.rwth-aachen.de/fb-fi/ops/docker-ros-ci/-/pipelines/$PIPELINE_ID)" if [[ $PIPELINE_STATUS == "success" ]]; then break - elif [[ $PIPELINE_STATUS == "failed" ]] || [[ $PIPELINE_STATUS == "canceled" ]]; then + elif [[ $PIPELINE_STATUS == "failed" ]]; then exit 1 - fi - done - - watch-ros2: - name: Watch ROS2 - runs-on: ubuntu-latest - needs: trigger-ros2 - steps: - - name: Wait for pipeline completion - run: | - export PIPELINE_ID=$(cat artifacts/id) - while true; do - sleep 30 - export PIPELINE_STATUS=$(curl --silent --header "PRIVATE-TOKEN: ${{ secrets.DOCKER_ROS_CI_READ_PIPELINE_GITLAB_TOKEN }}" \ - "https://gitlab.ika.rwth-aachen.de/api/v4/projects/1886/pipelines/$PIPELINE_ID" \ - | jq -r .status) - echo "Pipeline status: $PIPELINE_STATUS (https://gitlab.ika.rwth-aachen.de/fb-fi/ops/docker-ros-ci/-/pipelines/$PIPELINE_ID)" - if [[ $PIPELINE_STATUS == "success" ]]; then - break - elif [[ $PIPELINE_STATUS == "failed" ]] || [[ $PIPELINE_STATUS == "canceled" ]]; then + elif [[ $PIPELINE_STATUS == "canceled" ]]; then exit 1 fi - done \ No newline at end of file + done From 2428e27eaf5fc3f6594e5c4075824bf5bcc22568 Mon Sep 17 00:00:00 2001 From: Lennart Reiher Date: Tue, 6 Jun 2023 18:28:46 +0200 Subject: [PATCH 133/159] use github artifact action to fix gitlab ci workflow --- .github/workflows/gitlab.yml | 16 +++++++++++----- 1 file changed, 11 insertions(+), 5 deletions(-) diff --git a/.github/workflows/gitlab.yml b/.github/workflows/gitlab.yml index 58a1a5b..1efd13e 100644 --- a/.github/workflows/gitlab.yml +++ b/.github/workflows/gitlab.yml @@ -8,21 +8,27 @@ jobs: name: trigger runs-on: ubuntu-latest steps: - - name: Checkout repository - uses: actions/checkout@v2 - name: Trigger pipeline run: | - mkdir artifacts - curl --silent --fail --request POST --form "token=${{ secrets.DOCKER_ROS_CI_TRIGGER_GITLAB_TOKEN }}" --form "ref=main" --form "variables[DOCKER_ROS_GIT_REF]=$(git rev-parse HEAD)" "https://gitlab.ika.rwth-aachen.de/api/v4/projects/1886/trigger/pipeline" | jq -r .id > artifacts/id + curl --silent --fail --request POST --form "token=${{ secrets.DOCKER_ROS_CI_TRIGGER_GITLAB_TOKEN }}" --form "ref=main" --form "variables[DOCKER_ROS_GIT_REF]=$(git rev-parse HEAD)" "https://gitlab.ika.rwth-aachen.de/api/v4/projects/1886/trigger/pipeline" | jq -r .id > id + - name: Upload pipeline ID + uses: actions/upload-artifact@v3 + with: + name: id + path: id watch: name: watch runs-on: ubuntu-latest needs: trigger steps: + - name: Get pipeline ID + uses: actions/download-artifact@v3 + with: + name: id - name: Wait for pipeline completion run: | - PIPELINE_ID=$(cat artifacts/id) + PIPELINE_ID=$(cat id) while true; do sleep 30 PIPELINE_STATUS=$(curl --silent --header "PRIVATE-TOKEN: ${{ secrets.DOCKER_ROS_CI_READ_PIPELINE_GITLAB_TOKEN }}" "https://gitlab.ika.rwth-aachen.de/api/v4/projects/1886/pipelines/$PIPELINE_ID" | jq -r .status) From b94010e3217672346e5cfe17ada47452ba306c24 Mon Sep 17 00:00:00 2001 From: Lennart Reiher Date: Tue, 6 Jun 2023 18:31:28 +0200 Subject: [PATCH 134/159] add badge for gitlab workflow --- README.md | 1 + 1 file changed, 1 insertion(+) diff --git a/README.md b/README.md index 938c4a9..7cace44 100644 --- a/README.md +++ b/README.md @@ -3,6 +3,7 @@

+

*docker-ros* automatically builds minimal container images of ROS applications. From 0b4611db4764de5cdad9da0c614b23a82635831c Mon Sep 17 00:00:00 2001 From: Lennart Reiher Date: Tue, 6 Jun 2023 18:46:59 +0200 Subject: [PATCH 135/159] fix passing of docker-ros-git-ref to docker-ros-ci --- .github/workflows/gitlab.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/gitlab.yml b/.github/workflows/gitlab.yml index 1efd13e..6f376db 100644 --- a/.github/workflows/gitlab.yml +++ b/.github/workflows/gitlab.yml @@ -10,7 +10,7 @@ jobs: steps: - name: Trigger pipeline run: | - curl --silent --fail --request POST --form "token=${{ secrets.DOCKER_ROS_CI_TRIGGER_GITLAB_TOKEN }}" --form "ref=main" --form "variables[DOCKER_ROS_GIT_REF]=$(git rev-parse HEAD)" "https://gitlab.ika.rwth-aachen.de/api/v4/projects/1886/trigger/pipeline" | jq -r .id > id + curl --silent --fail --request POST --form "token=${{ secrets.DOCKER_ROS_CI_TRIGGER_GITLAB_TOKEN }}" --form "ref=main" --form "variables[DOCKER_ROS_GIT_REF]=${{ github.sha }}" "https://gitlab.ika.rwth-aachen.de/api/v4/projects/1886/trigger/pipeline" | jq -r .id > id - name: Upload pipeline ID uses: actions/upload-artifact@v3 with: From e3815148a40921e18df8d981760be7e030a433ce Mon Sep 17 00:00:00 2001 From: Lennart Reiher Date: Tue, 6 Jun 2023 18:50:00 +0200 Subject: [PATCH 136/159] trigger two gitlab ci pipelines --- .github/workflows/gitlab.yml | 44 ++++++++++++++++++++++++++++++++---- 1 file changed, 39 insertions(+), 5 deletions(-) diff --git a/.github/workflows/gitlab.yml b/.github/workflows/gitlab.yml index 6f376db..45e7005 100644 --- a/.github/workflows/gitlab.yml +++ b/.github/workflows/gitlab.yml @@ -4,8 +4,7 @@ on: [push] jobs: - trigger: - name: trigger + trigger-ros: runs-on: ubuntu-latest steps: - name: Trigger pipeline @@ -17,10 +16,45 @@ jobs: name: id path: id - watch: - name: watch + watch-ros: runs-on: ubuntu-latest - needs: trigger + needs: trigger-ros + steps: + - name: Get pipeline ID + uses: actions/download-artifact@v3 + with: + name: id + - name: Wait for pipeline completion + run: | + PIPELINE_ID=$(cat id) + while true; do + sleep 30 + PIPELINE_STATUS=$(curl --silent --header "PRIVATE-TOKEN: ${{ secrets.DOCKER_ROS_CI_READ_PIPELINE_GITLAB_TOKEN }}" "https://gitlab.ika.rwth-aachen.de/api/v4/projects/1886/pipelines/$PIPELINE_ID" | jq -r .status) + echo "Pipeline status: $PIPELINE_STATUS (https://gitlab.ika.rwth-aachen.de/fb-fi/ops/docker-ros-ci/-/pipelines/$PIPELINE_ID)" + if [[ $PIPELINE_STATUS == "success" ]]; then + break + elif [[ $PIPELINE_STATUS == "failed" ]]; then + exit 1 + elif [[ $PIPELINE_STATUS == "canceled" ]]; then + exit 1 + fi + done + + trigger-ros2: + runs-on: ubuntu-latest + steps: + - name: Trigger pipeline + run: | + curl --silent --fail --request POST --form "token=${{ secrets.DOCKER_ROS_CI_TRIGGER_GITLAB_TOKEN }}" --form "ref=ros2" --form "variables[DOCKER_ROS_GIT_REF]=${{ github.sha }}" "https://gitlab.ika.rwth-aachen.de/api/v4/projects/1886/trigger/pipeline" | jq -r .id > id + - name: Upload pipeline ID + uses: actions/upload-artifact@v3 + with: + name: id + path: id + + watch-ros2: + runs-on: ubuntu-latest + needs: trigger-ros2 steps: - name: Get pipeline ID uses: actions/download-artifact@v3 From d3932ecf4d45b42f0458b27983b78b6e5463906a Mon Sep 17 00:00:00 2001 From: Lennart Reiher Date: Tue, 6 Jun 2023 18:54:32 +0200 Subject: [PATCH 137/159] remove .gitlab-ci.yml, triggered by github workflow --- .gitlab-ci.yml | 45 --------------------------------------------- 1 file changed, 45 deletions(-) delete mode 100644 .gitlab-ci.yml diff --git a/.gitlab-ci.yml b/.gitlab-ci.yml deleted file mode 100644 index 4894639..0000000 --- a/.gitlab-ci.yml +++ /dev/null @@ -1,45 +0,0 @@ -stages: - - Trigger - - Watch - - -default: - image: badouralix/curl-jq - - -.trigger: - stage: Trigger - script: - - mkdir artifacts - - curl --silent --fail --request POST --form token=$DOCKER_ROS_CI_TRIGGER_TOKEN --form ref=$DOCKER_ROS_CI_GIT_REF --form "variables[DOCKER_ROS_GIT_REF]=$CI_COMMIT_SHA" "https://gitlab.ika.rwth-aachen.de/api/v4/projects/1886/trigger/pipeline" | jq -r .id > artifacts/id - artifacts: - paths: [artifacts] - expire_in: 1h - -Trigger ROS1: - extends: .trigger - variables: - DOCKER_ROS_CI_GIT_REF: test/docker-ros-refactor - - -.watch: - stage: Watch - script: - - PIPELINE_ID=$(cat artifacts/id) - - |- - while true; do - sleep 30 - PIPELINE_STATUS=$(curl --silent --header "PRIVATE-TOKEN: $DOCKER_ROS_CI_READ_PIPELINE_TOKEN" "https://gitlab.ika.rwth-aachen.de/api/v4/projects/1886/pipelines/$PIPELINE_ID" | jq -r .status) - echo "Pipeline status: $PIPELINE_STATUS (https://gitlab.ika.rwth-aachen.de/fb-fi/ops/docker-ros-ci/-/pipelines/$PIPELINE_ID)" - if [[ $PIPELINE_STATUS == "success" ]]; then - break - elif [[ $PIPELINE_STATUS == "failed" ]]; then - exit 1 - elif [[ $PIPELINE_STATUS == "canceled" ]]; then - exit 1 - fi - done - -Watch ROS1: - extends: .watch - needs: [Trigger ROS1] From 706b633be7a1ff4877491cce7af18111750c939e Mon Sep 17 00:00:00 2001 From: Jean-Pierre Busch Date: Tue, 6 Jun 2023 20:04:05 +0200 Subject: [PATCH 138/159] update gitlab-ci.template.yml --- templates/.gitlab-ci.template.yml | 82 +++++++++++++++++-------------- 1 file changed, 44 insertions(+), 38 deletions(-) diff --git a/templates/.gitlab-ci.template.yml b/templates/.gitlab-ci.template.yml index c25f192..7addc0f 100644 --- a/templates/.gitlab-ci.template.yml +++ b/templates/.gitlab-ci.template.yml @@ -24,27 +24,27 @@ variables: ENABLE_INDUSTRIAL_CI: 'false' # Enable industrial_ci ENABLE_SINGLEARCH_PUSH: 'false' # Enable push of single arch images with [-amd64|-arm64] postfix PUSH_AS_LATEST: 'false' # Push image additionally with tag 'latest' - GIT_HTTPS_SERVER: ${CI_SERVER_HOST}:${CI_SERVER_PORT} # git server address for private repositories without protocol (e.g. github.com) + GIT_HTTPS_SERVER: ${CI_SERVER_HOST} # git server address for private repositories without protocol (e.g. github.com) GIT_HTTPS_USER: gitlab-ci-token # git https username for private repository access GIT_HTTPS_PASSWORD: ${CI_JOB_TOKEN} # git https password/token for private repository access # ----- - DOCKER_ROS_GIT_REF: main + DOCKER_ROS_GIT_REF: main - _RUN_IMAGE: ${IMAGE_NAME}:${IMAGE_TAG} - _DEV_IMAGE: ${DEV_IMAGE_NAME}:${DEV_IMAGE_TAG} + _RUN_IMAGE: ${IMAGE_NAME}:${IMAGE_TAG} + _DEV_IMAGE: ${DEV_IMAGE_NAME}:${DEV_IMAGE_TAG} - _IMAGE_DEV_CI: ${_DEV_IMAGE}_${CI_COMMIT_REF_SLUG}_ci - _IMAGE_RUN_CI: ${_RUN_IMAGE}_${CI_COMMIT_REF_SLUG}_ci - _IMAGE_DEV_CI_AMD64: ${_IMAGE_DEV_CI}-amd64 - _IMAGE_DEV_CI_ARM64: ${_IMAGE_DEV_CI}-arm64 - _IMAGE_RUN_CI_AMD64: ${_IMAGE_RUN_CI}-amd64 - _IMAGE_RUN_CI_ARM64: ${_IMAGE_RUN_CI}-arm64 - _IMAGE_DEV_LATEST: ${DEV_IMAGE_NAME}:latest-dev - _IMAGE_RUN_LATEST: ${IMAGE_NAME}:latest - _IMAGE_DEV_TARGET_TAG: ${_DEV_IMAGE}-${CI_COMMIT_TAG} - _IMAGE_RUN_TARGET_TAG: ${_RUN_IMAGE}-${CI_COMMIT_TAG} - _IMAGE_DEV_TAG: ${DEV_IMAGE_NAME}:${CI_COMMIT_TAG}-dev - _IMAGE_RUN_TAG: ${IMAGE_NAME}:${CI_COMMIT_TAG} + _IMAGE_DEV_CI: ${_DEV_IMAGE}_${CI_COMMIT_REF_SLUG}_ci + _IMAGE_RUN_CI: ${_RUN_IMAGE}_${CI_COMMIT_REF_SLUG}_ci + _IMAGE_DEV_CI_AMD64: ${_IMAGE_DEV_CI}-amd64 + _IMAGE_DEV_CI_ARM64: ${_IMAGE_DEV_CI}-arm64 + _IMAGE_RUN_CI_AMD64: ${_IMAGE_RUN_CI}-amd64 + _IMAGE_RUN_CI_ARM64: ${_IMAGE_RUN_CI}-arm64 + _IMAGE_DEV_LATEST: ${DEV_IMAGE_NAME}:latest-dev + _IMAGE_RUN_LATEST: ${IMAGE_NAME}:latest + _IMAGE_DEV_TARGET_TAG: ${_DEV_IMAGE}-${CI_COMMIT_TAG} + _IMAGE_RUN_TARGET_TAG: ${_RUN_IMAGE}-${CI_COMMIT_TAG} + _IMAGE_DEV_TAG: ${DEV_IMAGE_NAME}:${CI_COMMIT_TAG}-dev + _IMAGE_RUN_TAG: ${IMAGE_NAME}:${CI_COMMIT_TAG} GIT_SUBMODULE_STRATEGY: recursive DOCKER_DRIVER: overlay2 @@ -67,7 +67,7 @@ default: - privileged - amd64 before_script: - - apk add bash dpkg + - apk add bash - cd ${BUILD_CONTEXT} - |- if [[ ! -d $docker/docker-ros ]]; then @@ -79,10 +79,8 @@ default: cd - fi - |- - if [[ $(dpkg --print-architecture) != ${PLATFORM} ]]; then + if [[ ${CI_RUNNER_EXECUTABLE_ARCH} != ${PLATFORM} && ${CI_RUNNER_EXECUTABLE_ARCH} != linux/${PLATFORM} ]]; then docker run --rm --privileged multiarch/qemu-user-static --reset -p yes - dpkg --print-architecture - echo ${CI_RUNNER_EXECUTABLE_ARCH} fi - docker login -u ${REGISTRY_USERNAME} -p ${REGISTRY_PASSWORD} ${REGISTRY} - docker context create buildx-context @@ -90,29 +88,33 @@ default: .build: script: - - PLATFORM=${BUILD_PLATFORM} TARGET=${BUILD_TARGET} ./docker/docker-ros/scripts/ci.sh + - TARGET=${BUILD_TARGET} PLATFORM=${BUILD_PLATFORM} ./docker/docker-ros/scripts/ci.sh - docker push ${IMAGE} dev-amd64: stage: Build dev Images extends: .build rules: - - if: $PLATFORM =~ 'amd64' && $TARGET =~ 'dev' + - if: $PLATFORM =~ /.*amd64.*/ && $TARGET =~ /.*dev.*/ variables: BUILD_PLATFORM: amd64 BUILD_TARGET: dev IMAGE: ${_IMAGE_DEV_CI_AMD64} + ENABLE_SINGLEARCH_PUSH: 'true' + _IMAGE_POSTFIX: _${CI_COMMIT_REF_SLUG}_ci dev-arm64: stage: Build dev Images extends: .build tags: [privileged, arm64] rules: - - if: $PLATFORM =~ 'arm64' && $TARGET =~ 'dev' + - if: $PLATFORM =~ /.*arm64.*/ && $TARGET =~ /.*dev.*/ variables: BUILD_PLATFORM: arm64 BUILD_TARGET: dev IMAGE: ${_IMAGE_DEV_CI_ARM64} + ENABLE_SINGLEARCH_PUSH: 'true' + _IMAGE_POSTFIX: _${CI_COMMIT_REF_SLUG}_ci run-amd64: stage: Build run Images @@ -121,12 +123,14 @@ run-amd64: - job: dev-amd64 optional: true rules: - - if: $PLATFORM =~ 'amd64' && $TARGET =~ 'run' + - if: $PLATFORM =~ /.*amd64.*/ && $TARGET =~ /.*run.*/ variables: BUILD_PLATFORM: amd64 COMMAND: ${COMMAND} BUILD_TARGET: run IMAGE: ${_IMAGE_RUN_CI_AMD64} + ENABLE_SINGLEARCH_PUSH: 'true' + _IMAGE_POSTFIX: _${CI_COMMIT_REF_SLUG}_ci run-arm64: stage: Build run Images @@ -136,12 +140,14 @@ run-arm64: - job: dev-arm64 optional: true rules: - - if: $PLATFORM =~ 'arm64' && $TARGET =~ 'run' + - if: $PLATFORM =~ /.*arm64.*/ && $TARGET =~ /.*run.*/ variables: BUILD_PLATFORM: arm64 COMMAND: ${COMMAND} BUILD_TARGET: run IMAGE: ${_IMAGE_RUN_CI_ARM64} + ENABLE_SINGLEARCH_PUSH: 'true' + _IMAGE_POSTFIX: _${CI_COMMIT_REF_SLUG}_ci .test: @@ -165,7 +171,7 @@ Test dev-amd64: - job: dev-amd64 optional: true rules: - - if: $ENABLE_INDUSTRIAL_CI == 'true' && $PLATFORM =~ 'amd64' + - if: $ENABLE_INDUSTRIAL_CI == 'true' && $PLATFORM =~ /.*amd64.*/ variables: DOCKER_IMAGE: ${_IMAGE_DEV_CI_AMD64} @@ -177,7 +183,7 @@ Test dev-arm64: - job: dev-arm64 optional: true rules: - - if: $ENABLE_INDUSTRIAL_CI == 'true' && $PLATFORM =~ 'arm64' + - if: $ENABLE_INDUSTRIAL_CI == 'true' && $PLATFORM =~ /.*arm64.*/ variables: DOCKER_IMAGE: ${_IMAGE_DEV_CI_ARM64} @@ -201,19 +207,19 @@ Test dev-arm64: when: never script: - |- - if [[ ${PLATFORM} =~ 'amd64' && ${PLATFORM} =~ 'arm64' ]]; then - [[ ${TARGET} =~ 'dev' ]] && docker manifest create ${IMG_DEV} --amend ${_IMAGE_DEV_CI_AMD64} --amend ${_IMAGE_DEV_CI_ARM64} - [[ ${TARGET} =~ 'run' ]] && docker manifest create ${IMG_RUN} --amend ${_IMAGE_RUN_CI_AMD64} --amend ${_IMAGE_RUN_CI_ARM64} - elif [[ ${PLATFORM} == 'amd64' ]]; then - [[ ${TARGET} =~ 'dev' ]] && docker manifest create ${IMG_DEV} --amend ${_IMAGE_DEV_CI_AMD64} - [[ ${TARGET} =~ 'run' ]] && docker manifest create ${IMG_RUN} --amend ${_IMAGE_RUN_CI_AMD64} - elif [[ ${PLATFORM} == 'amd64' ]]; then - [[ ${TARGET} =~ 'dev' ]] && docker manifest create ${IMG_DEV} --amend ${_IMAGE_DEV_CI_ARM64} - [[ ${TARGET} =~ 'run' ]] && docker manifest create ${IMG_RUN} --amend ${_IMAGE_RUN_CI_ARM64} + if [[ ${PLATFORM} =~ amd64 && ${PLATFORM} =~ arm64 ]]; then + [[ ${TARGET} =~ dev ]] && docker manifest create ${IMG_DEV} --amend ${_IMAGE_DEV_CI_AMD64} --amend ${_IMAGE_DEV_CI_ARM64} + [[ ${TARGET} =~ run ]] && docker manifest create ${IMG_RUN} --amend ${_IMAGE_RUN_CI_AMD64} --amend ${_IMAGE_RUN_CI_ARM64} + elif [[ ${PLATFORM} == amd64 ]]; then + [[ ${TARGET} =~ dev ]] && docker manifest create ${IMG_DEV} --amend ${_IMAGE_DEV_CI_AMD64} + [[ ${TARGET} =~ run ]] && docker manifest create ${IMG_RUN} --amend ${_IMAGE_RUN_CI_AMD64} + elif [[ ${PLATFORM} == arm64 ]]; then + [[ ${TARGET} =~ dev ]] && docker manifest create ${IMG_DEV} --amend ${_IMAGE_DEV_CI_ARM64} + [[ ${TARGET} =~ run ]] && docker manifest create ${IMG_RUN} --amend ${_IMAGE_RUN_CI_ARM64} fi - |- - [[ ${TARGET} =~ 'dev' ]] && docker manifest push ${IMG_DEV} - [[ ${TARGET} =~ 'dev' ]] && docker manifest push ${IMG_RUN} + [[ ${TARGET} =~ dev ]] && docker manifest push ${IMG_DEV} + [[ ${TARGET} =~ run ]] && docker manifest push ${IMG_RUN} Push CI: stage: Push Multi-Arch Images From 961f2287be90dce56ea81507d750a45b29f36bf8 Mon Sep 17 00:00:00 2001 From: Jean-Pierre Busch Date: Tue, 6 Jun 2023 20:11:37 +0200 Subject: [PATCH 139/159] change ref of docker-ros-ci to main --- .github/workflows/main.yml | 6 ++---- 1 file changed, 2 insertions(+), 4 deletions(-) diff --git a/.github/workflows/main.yml b/.github/workflows/main.yml index 8e13a6a..b08a8a9 100644 --- a/.github/workflows/main.yml +++ b/.github/workflows/main.yml @@ -10,9 +10,8 @@ jobs: with: owner: ika-rwth-aachen repo: docker-ros-ci - ref: feature/github-workflow # TODO: set to main + ref: main workflow_file_name: main-ros1.yml - github_token: ${{ secrets.PAT }} # Personal Access Token with appropriate permissions client_payload: '{"docker-ros-git-ref": "${{ github.ref_name }}"}' trigger-docker-ros-ci-ros2: name: Trigger docker-ros-ci ros2 workflow @@ -23,7 +22,6 @@ jobs: with: owner: ika-rwth-aachen repo: docker-ros-ci - ref: feature/github-workflow # TODO: set to main + ref: main workflow_file_name: main-ros2.yml - github_token: ${{ secrets.PAT }} # Personal Access Token with appropriate permissions client_payload: '{"docker-ros-git-ref": "${{ github.ref_name }}"}' \ No newline at end of file From 12429d50bb87c49e3f65a4bd943fb16f6ee18ff4 Mon Sep 17 00:00:00 2001 From: Lennart Reiher Date: Tue, 6 Jun 2023 21:15:51 +0200 Subject: [PATCH 140/159] rename github workflow --- .github/workflows/github.yml | 27 +++++++++++++++++++++++++++ .github/workflows/main.yml | 27 --------------------------- README.md | 1 + 3 files changed, 28 insertions(+), 27 deletions(-) create mode 100644 .github/workflows/github.yml delete mode 100644 .github/workflows/main.yml diff --git a/.github/workflows/github.yml b/.github/workflows/github.yml new file mode 100644 index 0000000..5af94e3 --- /dev/null +++ b/.github/workflows/github.yml @@ -0,0 +1,27 @@ +name: GitHub + +on: [push] + +jobs: + + trigger-ros: + runs-on: ubuntu-latest + steps: + - uses: convictional/trigger-workflow-and-wait@v1.6.5 + with: + owner: ika-rwth-aachen + repo: docker-ros-ci + ref: main + workflow_file_name: ros.yml + client_payload: '{"docker-ros-git-ref": "${{ github.sha }}"}' + + trigger-ros2: + runs-on: ubuntu-latest + steps: + - uses: convictional/trigger-workflow-and-wait@v1.6.5 + with: + owner: ika-rwth-aachen + repo: docker-ros-ci + ref: main + workflow_file_name: ros2.yml + client_payload: '{"docker-ros-git-ref": "${{ github.sha }}"}' diff --git a/.github/workflows/main.yml b/.github/workflows/main.yml deleted file mode 100644 index b08a8a9..0000000 --- a/.github/workflows/main.yml +++ /dev/null @@ -1,27 +0,0 @@ -on: [push] - -jobs: - trigger-docker-ros-ci-ros1: - name: Trigger docker-ros-ci ros1 workflow - runs-on: ubuntu-latest - steps: - - name: Trigger docker-ros-ci ros1 workflow - uses: convictional/trigger-workflow-and-wait@v1.6.5 - with: - owner: ika-rwth-aachen - repo: docker-ros-ci - ref: main - workflow_file_name: main-ros1.yml - client_payload: '{"docker-ros-git-ref": "${{ github.ref_name }}"}' - trigger-docker-ros-ci-ros2: - name: Trigger docker-ros-ci ros2 workflow - runs-on: ubuntu-latest - steps: - - name: Trigger docker-ros-ci ros2 - uses: convictional/trigger-workflow-and-wait@v1.6.5 - with: - owner: ika-rwth-aachen - repo: docker-ros-ci - ref: main - workflow_file_name: main-ros2.yml - client_payload: '{"docker-ros-git-ref": "${{ github.ref_name }}"}' \ No newline at end of file diff --git a/README.md b/README.md index 7cace44..522a8b3 100644 --- a/README.md +++ b/README.md @@ -3,6 +3,7 @@

+

From de1459b96f7044e4ee13c35c469fda889cec781e Mon Sep 17 00:00:00 2001 From: Lennart Reiher Date: Tue, 6 Jun 2023 21:29:10 +0200 Subject: [PATCH 141/159] re-add token for triggering github docker-ros-ci --- .github/workflows/github.yml | 2 ++ 1 file changed, 2 insertions(+) diff --git a/.github/workflows/github.yml b/.github/workflows/github.yml index 5af94e3..92aad0e 100644 --- a/.github/workflows/github.yml +++ b/.github/workflows/github.yml @@ -14,6 +14,7 @@ jobs: ref: main workflow_file_name: ros.yml client_payload: '{"docker-ros-git-ref": "${{ github.sha }}"}' + github_token: ${{ secrets.DOCKER_ROS_CI_TRIGGER_GITHUB_TOKEN }} trigger-ros2: runs-on: ubuntu-latest @@ -25,3 +26,4 @@ jobs: ref: main workflow_file_name: ros2.yml client_payload: '{"docker-ros-git-ref": "${{ github.sha }}"}' + github_token: ${{ secrets.DOCKER_ROS_CI_TRIGGER_GITHUB_TOKEN }} From e68f4912c62deb01b28cc7a3f07ad789f5431257 Mon Sep 17 00:00:00 2001 From: Jean-Pierre Busch Date: Tue, 6 Jun 2023 21:53:50 +0200 Subject: [PATCH 142/159] move qemu istallation to build job --- templates/.gitlab-ci.template.yml | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/templates/.gitlab-ci.template.yml b/templates/.gitlab-ci.template.yml index 7addc0f..a17f446 100644 --- a/templates/.gitlab-ci.template.yml +++ b/templates/.gitlab-ci.template.yml @@ -78,16 +78,16 @@ default: git checkout FETCH_HEAD cd - fi - - |- - if [[ ${CI_RUNNER_EXECUTABLE_ARCH} != ${PLATFORM} && ${CI_RUNNER_EXECUTABLE_ARCH} != linux/${PLATFORM} ]]; then - docker run --rm --privileged multiarch/qemu-user-static --reset -p yes - fi - docker login -u ${REGISTRY_USERNAME} -p ${REGISTRY_PASSWORD} ${REGISTRY} - docker context create buildx-context - docker buildx create --use buildx-context .build: script: + - |- + if [[ ${CI_RUNNER_EXECUTABLE_ARCH} != ${BUILD_PLATFORM} && ${CI_RUNNER_EXECUTABLE_ARCH} != linux/${BUILD_PLATFORM} ]]; then + docker run --rm --privileged multiarch/qemu-user-static --reset -p yes + fi - TARGET=${BUILD_TARGET} PLATFORM=${BUILD_PLATFORM} ./docker/docker-ros/scripts/ci.sh - docker push ${IMAGE} From e483c84966be11f04fc6fbc90f8dc7e8c33b632b Mon Sep 17 00:00:00 2001 From: Lennart Reiher Date: Tue, 6 Jun 2023 22:12:09 +0200 Subject: [PATCH 143/159] convert table of config variables to more readable list --- README.md | 85 +++++++++++++++++++++++++++++++++++++++++-------------- 1 file changed, 63 insertions(+), 22 deletions(-) diff --git a/README.md b/README.md index 522a8b3..4fe0532 100644 --- a/README.md +++ b/README.md @@ -191,25 +191,66 @@ jobs: ## Configuration Variables -| GitHub Input | GitLab Env Var | Required | Description | Default GitHub | Default GitLab | Allow. Values | -| --- | --- | :---: | --- | :---: | :---: | :---: | -| `base_image` | `BASE_IMAGE` | x | Base image `name:tag` | - | - | - | -| `build-context` | `BUILD_CONTEXT` | - | Build context of Docker build process | `${{ github.workspace }}` | `.` | - | -| `command` | `COMMAND` | - | Launch command of run image (required if `target=run`) | - | - | - | -| `dev-image-name` | `DEV_IMAGE_NAME` | - | Image name of dev image | | | - | -| `dev-image-tag` | `DEV_IMAGE_TAG` | - | Image tag of dev image | `` | `"-dev` | - | -| - | `DOCKER_ROS_GIT_REF` | - | Git reference of *docker-ros* to run in CI | - | `main` | - | -| `enable-industrial-ci` | `ENABLE_INDUSTRIAL_CI` | - | Enable industrial_ci | `false` | `false` | `true`, `false` | -| `enable-singlearch-push` | `ENABLE_SINGLEARCH_PUSH` | - | Enable push of single arch images with `-amd64`/`-arm64` postfix | `false` | `false` | `true`, `false` | -| `git-https-password` | `GIT_HTTPS_PASSWORD` | - | Password for cloning private Git repositories via HTTPS | `${{ github.token }}` | `$CI_JOB_TOKEN` | - | -| `git-https-server` | `GIT_HTTPS_SERVER` | - | Server URL (without protocol) for cloning private Git repositories via HTTPS | `github.com` | `$CI_SERVER_HOST:$CI_SERVER_PORT` | - | -| `git-https-user` | `GIT_HTTPS_USER` | - | Username for cloning private Git repositories via HTTPS | `${{ github.actor }}` | `gitlab-ci-token` | | -| `git-ssh-known-host-keys` | `GIT_SSH_KNOWN_HOST_KEYS` | - | Known SSH host keys for cloning private Git repositories via SSH (may be obtained using `ssh-keyscan`) | - | - | - | -| `git-ssh-private-key` | `GIT_SSH_PRIVATE_KEY` | - | SSH private key for cloning private Git repositories via SSH | - | - | - | -| `image-name` | `IMAGE_NAME` | - | Image name of run image | `ghcr.io/${{ github.repository }}` | `$CI_REGISTRY_IMAGE` | - | -| `image-tag` | `IMAGE_TAG` | - | Image tag of run image | `latest` | `latest` | - | -| `platform` | `PLATFORM` | - | Target platform architecture (comma-separated list) | runner architecture | runner architecture | `amd64`, `arm64` | -| `registry-password` | `REGISTRY_PASSWORD` | - | Docker registry password | `${{ github.token }}` | `$CI_REGISTRY_PASSWORD` | - | -| `registry-username` | `REGISTRY_USERNAME` | - | Docker registry username | `${{ github.actor }}` | `$CI_REGISTRY_USER` | - | -| `registry` | `REGISTRY` | - | Docker registry to push images to | `ghcr.io` | `$CI_REGISTRY` | - | -| `target` | `TARGET` | - | Target stage of Dockerfile (comma-separated list) | `run` | `run` | `dev`, `run`, `dev,run` | +> **Note** +> *GitHub Action input* | *GitLab CI environment variable* + +- **`base-image` | `BASE_IMAGE`** + Base image `name:tag` + *required* +- **`build-context` | `BUILD_CONTEXT`** + Build context of Docker build process + *default:* `${{ github.workspace }}` | `.` +- **`command` | `COMMAND`** + Launch command of run image + *required if `target=run`* +- **`dev-image-name` | `DEV_IMAGE_NAME`** + Image name of dev image + *default:* `` +- **`dev-image-tag` | `DEV_IMAGE_TAG`** + Image tag of dev image + *default:* `-dev` +- **`-` | `DOCKER_ROS_GIT_REF`** + Git reference of *docker-ros* to run in CI + *default:* `main` +- **`enable-industrial-ci` | `ENABLE_INDUSTRIAL_CI`** + Enable [*industrial_ci*](https://github.com/ros-industrial/industrial_ci) + *default:* `false` +- **`enable-singlearch-push` | `ENABLE_SINGLEARCH_PUSH`** + Enable push of single arch images with `-amd64`/`-arm64` postfix + *default:* `false` +- **`git-https-password` | `GIT_HTTPS_PASSWORD`** + Password for cloning private Git repositories via HTTPS + *default:* `${{ github.token }}` | `$CI_JOB_TOKEN` +- **`git-https-server` | `GIT_HTTPS_SERVER`** + Server URL (without protocol) for cloning private Git repositories via HTTPS + *default:* `github.com` | `$CI_SERVER_HOST:$CI_SERVER_PORT` +- **`git-https-user` | `GIT_HTTPS_USER`** + Username for cloning private Git repositories via HTTPS + *default:* `${{ github.actor }}` | `gitlab-ci-token` +- **`git-ssh-known-host-keys` | `GIT_SSH_KNOWN_HOST_KEYS`** + Known SSH host keys for cloning private Git repositories via SSH (may be obtained using `ssh-keyscan`) +- **`git-ssh-private-key` | `GIT_SSH_PRIVATE_KEY`** + SSH private key for cloning private Git repositories via SSH +- **`image-name` | `IMAGE_NAME`** + Image name of run image + *default:* `ghcr.io/${{ github.repository }}` | `$CI_REGISTRY_IMAGE` +- **`image-tag` | `IMAGE_TAG`** + Image tag of run image + *default:* `latest` +- **`platform` | `PLATFORM`** + Target platform architecture (comma-separated list) + *default:* runner architecture + *supported values:* `amd64`, `arm64` +- **`registry-password` | `REGISTRY_PASSWORD`** + Docker registry password + *default:* `${{ github.token }}` | `$CI_REGISTRY_PASSWORD` +- **`registry-username` | `REGISTRY_USERNAME`** + Docker registry username + *default:* `${{ github.actor }}` | `$CI_REGISTRY_USER` +- **`registry` | `REGISTRY`** + Docker registry to push images to + *default:* `ghcr.io` | `$CI_REGISTRY` +- **`target` | `TARGET`** + Target stage of Dockerfile (comma-separated list) + *default:* `run` + *supported values:* `dev`, `run` From 306a8e8274c5e74c60fba951db66423556bdf88a Mon Sep 17 00:00:00 2001 From: Lennart Reiher Date: Tue, 6 Jun 2023 23:14:58 +0200 Subject: [PATCH 144/159] add missing variables to readme --- README.md | 3 +++ action.yml | 3 ++- templates/.gitlab-ci.template.yml | 2 +- 3 files changed, 6 insertions(+), 2 deletions(-) diff --git a/README.md b/README.md index 4fe0532..e3eb4e4 100644 --- a/README.md +++ b/README.md @@ -241,6 +241,9 @@ jobs: Target platform architecture (comma-separated list) *default:* runner architecture *supported values:* `amd64`, `arm64` +- **`push-as-latest` | `PUSH_AS_LATEST`** + Push images with tag `latest`/`latest-dev` in addition to the configured image names + *default:* `false` - **`registry-password` | `REGISTRY_PASSWORD`** Docker registry password *default:* `${{ github.token }}` | `$CI_REGISTRY_PASSWORD` diff --git a/action.yml b/action.yml index a820406..5b43bcc 100644 --- a/action.yml +++ b/action.yml @@ -74,9 +74,10 @@ inputs: default: false push-as-latest: - description: "Push image additionaly with 'latest' tag" + description: "Push images with tag `latest`/`latest-dev` in addition to the configured image names" default: false + runs: using: "composite" steps: diff --git a/templates/.gitlab-ci.template.yml b/templates/.gitlab-ci.template.yml index a17f446..8466fa0 100644 --- a/templates/.gitlab-ci.template.yml +++ b/templates/.gitlab-ci.template.yml @@ -23,7 +23,7 @@ variables: REGISTRY_PASSWORD: ${CI_REGISTRY_PASSWORD} # Docker registry password ENABLE_INDUSTRIAL_CI: 'false' # Enable industrial_ci ENABLE_SINGLEARCH_PUSH: 'false' # Enable push of single arch images with [-amd64|-arm64] postfix - PUSH_AS_LATEST: 'false' # Push image additionally with tag 'latest' + PUSH_AS_LATEST: 'false' # Push images with tag `latest`/`latest-dev` in addition to the configured image names GIT_HTTPS_SERVER: ${CI_SERVER_HOST} # git server address for private repositories without protocol (e.g. github.com) GIT_HTTPS_USER: gitlab-ci-token # git https username for private repository access GIT_HTTPS_PASSWORD: ${CI_JOB_TOKEN} # git https password/token for private repository access From fa1242b87e74b36f4d70ea070ea8e88b8a1c83e6 Mon Sep 17 00:00:00 2001 From: Lennart Reiher Date: Tue, 6 Jun 2023 23:17:49 +0200 Subject: [PATCH 145/159] add missing git ssh variables to .gitlab-ci template --- templates/.gitlab-ci.template.yml | 38 ++++++++++++++++--------------- 1 file changed, 20 insertions(+), 18 deletions(-) diff --git a/templates/.gitlab-ci.template.yml b/templates/.gitlab-ci.template.yml index 8466fa0..e5a3ba4 100644 --- a/templates/.gitlab-ci.template.yml +++ b/templates/.gitlab-ci.template.yml @@ -9,24 +9,26 @@ workflow: variables: - TARGET: run # Target stage of Dockerfile (comma-separated list) [dev|run] - PLATFORM: '' # Target platform architecture (comma-separated list) [amd64|arm64|...] - BASE_IMAGE: '' # Base image name:tag (required) - COMMAND: '' # Launch command of run image (required if target=run) - IMAGE_NAME: ${CI_REGISTRY_IMAGE} # Image name of run image - IMAGE_TAG: latest # Image tag of run image - DEV_IMAGE_NAME: ${IMAGE_NAME} # Image name of dev image - DEV_IMAGE_TAG: ${IMAGE_TAG}-dev # Image tag of dev image - BUILD_CONTEXT: . # Build context of Docker build process - REGISTRY: ${CI_REGISTRY} # Docker registry to push images to - REGISTRY_USERNAME: ${CI_REGISTRY_USER} # Docker registry username - REGISTRY_PASSWORD: ${CI_REGISTRY_PASSWORD} # Docker registry password - ENABLE_INDUSTRIAL_CI: 'false' # Enable industrial_ci - ENABLE_SINGLEARCH_PUSH: 'false' # Enable push of single arch images with [-amd64|-arm64] postfix - PUSH_AS_LATEST: 'false' # Push images with tag `latest`/`latest-dev` in addition to the configured image names - GIT_HTTPS_SERVER: ${CI_SERVER_HOST} # git server address for private repositories without protocol (e.g. github.com) - GIT_HTTPS_USER: gitlab-ci-token # git https username for private repository access - GIT_HTTPS_PASSWORD: ${CI_JOB_TOKEN} # git https password/token for private repository access + TARGET: run # Target stage of Dockerfile (comma-separated list) [dev|run] + PLATFORM: '' # Target platform architecture (comma-separated list) [amd64|arm64|...] + BASE_IMAGE: '' # Base image name:tag (required) + COMMAND: '' # Launch command of run image (required if target=run) + IMAGE_NAME: ${CI_REGISTRY_IMAGE} # Image name of run image + IMAGE_TAG: latest # Image tag of run image + DEV_IMAGE_NAME: ${IMAGE_NAME} # Image name of dev image + DEV_IMAGE_TAG: ${IMAGE_TAG}-dev # Image tag of dev image + BUILD_CONTEXT: . # Build context of Docker build process + REGISTRY: ${CI_REGISTRY} # Docker registry to push images to + REGISTRY_USERNAME: ${CI_REGISTRY_USER} # Docker registry username + REGISTRY_PASSWORD: ${CI_REGISTRY_PASSWORD} # Docker registry password + ENABLE_INDUSTRIAL_CI: 'false' # Enable industrial_ci + ENABLE_SINGLEARCH_PUSH: 'false' # Enable push of single arch images with [-amd64|-arm64] postfix + PUSH_AS_LATEST: 'false' # Push images with tag `latest`/`latest-dev` in addition to the configured image names + GIT_HTTPS_SERVER: ${CI_SERVER_HOST} # Server URL (without protocol) for cloning private Git repositories via HTTPS + GIT_HTTPS_USER: gitlab-ci-token # Username for cloning private Git repositories via HTTPS + GIT_HTTPS_PASSWORD: ${CI_JOB_TOKEN} # Password for cloning private Git repositories via HTTPS + GIT_SSH_PRIVATE_KEY: '' # SSH private key for cloning private Git repositories via SSH + GIT_SSH_KNOWN_HOST_KEYS: '' # Known SSH host keys for cloning private Git repositories via SSH (may be obtained using `ssh-keyscan`) # ----- DOCKER_ROS_GIT_REF: main From 5b33efa9bbf962aa6734464edc1f999c134d9ac0 Mon Sep 17 00:00:00 2001 From: Lennart Reiher Date: Tue, 6 Jun 2023 23:37:28 +0200 Subject: [PATCH 146/159] refine readme structure --- README.md | 38 +++++++++++++++++++++++++++++++++++++- 1 file changed, 37 insertions(+), 1 deletion(-) diff --git a/README.md b/README.md index e3eb4e4..cee944b 100644 --- a/README.md +++ b/README.md @@ -9,11 +9,19 @@ *docker-ros* automatically builds minimal container images of ROS applications. +- [About](#about) + - [Prerequisites](#prerequisites) - [Usage](#usage) - [Build a minimal image for deployment](#build-a-minimal-image-for-deployment) - [Build development and deployment images](#build-development-and-deployment-images) - [Build multi-arch images](#build-multi-arch-images) - [Build deployment image with additional industrial\_ci check](#build-deployment-image-with-additional-industrial_ci-check) + - [Build multi-arch images on arch-specific self-hosted runners in parallel](#build-multi-arch-images-on-arch-specific-self-hosted-runners-in-parallel) + - [Build images locally](#build-images-locally) +- [Advanced Dependencies](#advanced-dependencies) + - [Extra System Dependencies (apt)](#extra-system-dependencies-apt) + - [Custom Installation Script](#custom-installation-script) + - [Extra Image Files](#extra-image-files) - [Configuration Variables](#configuration-variables) We recommend to use *docker-ros* in combination with our other tools for Docker and ROS. @@ -23,11 +31,17 @@ We recommend to use *docker-ros* in combination with our other tools for Docker ## About -... +... TODO ... + +### Prerequisites + +... TODO ... ## Usage +... TODO ... + ### Build a minimal image for deployment
GitHub @@ -189,6 +203,28 @@ jobs:
+### Build images locally + +... TODO ... + + +## Advanced Dependencies + +... TODO ... + +### Extra System Dependencies (apt) + +... TODO ... + +### Custom Installation Script + +... TODO ... + +### Extra Image Files + +... TODO ... + + ## Configuration Variables > **Note** From 903eb868b5c1c30b69a3a810db16bb220aa8206b Mon Sep 17 00:00:00 2001 From: Jean-Pierre Busch Date: Wed, 7 Jun 2023 11:44:10 +0200 Subject: [PATCH 147/159] install qemu also for industrial_ci if necessary --- templates/.gitlab-ci.template.yml | 26 ++++++++++++++++---------- 1 file changed, 16 insertions(+), 10 deletions(-) diff --git a/templates/.gitlab-ci.template.yml b/templates/.gitlab-ci.template.yml index e5a3ba4..4100a25 100644 --- a/templates/.gitlab-ci.template.yml +++ b/templates/.gitlab-ci.template.yml @@ -87,10 +87,10 @@ default: .build: script: - |- - if [[ ${CI_RUNNER_EXECUTABLE_ARCH} != ${BUILD_PLATFORM} && ${CI_RUNNER_EXECUTABLE_ARCH} != linux/${BUILD_PLATFORM} ]]; then + if [[ ${CI_RUNNER_EXECUTABLE_ARCH} != ${_PLATFORM} && ${CI_RUNNER_EXECUTABLE_ARCH} != linux/${_PLATFORM} ]]; then docker run --rm --privileged multiarch/qemu-user-static --reset -p yes fi - - TARGET=${BUILD_TARGET} PLATFORM=${BUILD_PLATFORM} ./docker/docker-ros/scripts/ci.sh + - TARGET=${_TARGET} PLATFORM=${_PLATFORM} ./docker/docker-ros/scripts/ci.sh - docker push ${IMAGE} dev-amd64: @@ -99,8 +99,8 @@ dev-amd64: rules: - if: $PLATFORM =~ /.*amd64.*/ && $TARGET =~ /.*dev.*/ variables: - BUILD_PLATFORM: amd64 - BUILD_TARGET: dev + _PLATFORM: amd64 + _TARGET: dev IMAGE: ${_IMAGE_DEV_CI_AMD64} ENABLE_SINGLEARCH_PUSH: 'true' _IMAGE_POSTFIX: _${CI_COMMIT_REF_SLUG}_ci @@ -112,8 +112,8 @@ dev-arm64: rules: - if: $PLATFORM =~ /.*arm64.*/ && $TARGET =~ /.*dev.*/ variables: - BUILD_PLATFORM: arm64 - BUILD_TARGET: dev + _PLATFORM: arm64 + _TARGET: dev IMAGE: ${_IMAGE_DEV_CI_ARM64} ENABLE_SINGLEARCH_PUSH: 'true' _IMAGE_POSTFIX: _${CI_COMMIT_REF_SLUG}_ci @@ -127,9 +127,9 @@ run-amd64: rules: - if: $PLATFORM =~ /.*amd64.*/ && $TARGET =~ /.*run.*/ variables: - BUILD_PLATFORM: amd64 + _PLATFORM: amd64 + _TARGET: run COMMAND: ${COMMAND} - BUILD_TARGET: run IMAGE: ${_IMAGE_RUN_CI_AMD64} ENABLE_SINGLEARCH_PUSH: 'true' _IMAGE_POSTFIX: _${CI_COMMIT_REF_SLUG}_ci @@ -144,9 +144,9 @@ run-arm64: rules: - if: $PLATFORM =~ /.*arm64.*/ && $TARGET =~ /.*run.*/ variables: - BUILD_PLATFORM: arm64 + _PLATFORM: arm64 + _TARGET: run COMMAND: ${COMMAND} - BUILD_TARGET: run IMAGE: ${_IMAGE_RUN_CI_ARM64} ENABLE_SINGLEARCH_PUSH: 'true' _IMAGE_POSTFIX: _${CI_COMMIT_REF_SLUG}_ci @@ -162,6 +162,10 @@ run-arm64: before_script: - docker login -u ${REGISTRY_USERNAME} -p ${REGISTRY_PASSWORD} ${REGISTRY} - apk add --update bash coreutils grep tar + - |- + if [[ ${CI_RUNNER_EXECUTABLE_ARCH} != ${_PLATFORM} && ${CI_RUNNER_EXECUTABLE_ARCH} != linux/${_PLATFORM} ]]; then + docker run --rm --privileged multiarch/qemu-user-static --reset -p yes + fi - git clone --branch master --depth 1 https://github.com/ros-industrial/industrial_ci.git .industrial_ci - test -f ${BUILD_CONTEXT}/.repos || echo "repositories:" > ${BUILD_CONTEXT}/.repos script: .industrial_ci/gitlab.sh @@ -176,6 +180,7 @@ Test dev-amd64: - if: $ENABLE_INDUSTRIAL_CI == 'true' && $PLATFORM =~ /.*amd64.*/ variables: DOCKER_IMAGE: ${_IMAGE_DEV_CI_AMD64} + _PLATFORM: amd64 Test dev-arm64: stage: Test ROS Industrial CI @@ -188,6 +193,7 @@ Test dev-arm64: - if: $ENABLE_INDUSTRIAL_CI == 'true' && $PLATFORM =~ /.*arm64.*/ variables: DOCKER_IMAGE: ${_IMAGE_DEV_CI_ARM64} + _PLATFORM: arm64 .push: From 489a427f573eafd224eaabe54961083cf02e7c31 Mon Sep 17 00:00:00 2001 From: Jean-Pierre Busch Date: Wed, 7 Jun 2023 11:44:38 +0200 Subject: [PATCH 148/159] add collapsable sections for setup and push --- templates/.gitlab-ci.template.yml | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/templates/.gitlab-ci.template.yml b/templates/.gitlab-ci.template.yml index 4100a25..8fbd452 100644 --- a/templates/.gitlab-ci.template.yml +++ b/templates/.gitlab-ci.template.yml @@ -69,6 +69,7 @@ default: - privileged - amd64 before_script: + - echo -e "section_start:`date +%s`:setup_section[collapsed=true]\r\e[0KSetup docker-ros" - apk add bash - cd ${BUILD_CONTEXT} - |- @@ -83,6 +84,7 @@ default: - docker login -u ${REGISTRY_USERNAME} -p ${REGISTRY_PASSWORD} ${REGISTRY} - docker context create buildx-context - docker buildx create --use buildx-context + - echo -e "section_end:`date +%s`:setup_section\r\e[0K" .build: script: @@ -91,7 +93,9 @@ default: docker run --rm --privileged multiarch/qemu-user-static --reset -p yes fi - TARGET=${_TARGET} PLATFORM=${_PLATFORM} ./docker/docker-ros/scripts/ci.sh + - echo -e "section_start:`date +%s`:push_section[collapsed=true]\r\e[0KPush ${IMAGE}" - docker push ${IMAGE} + - echo -e "section_end:`date +%s`:push_section\r\e[0K" dev-amd64: stage: Build dev Images From 3357d2e4c3fc6842c3d7ca1311007d0feb30666c Mon Sep 17 00:00:00 2001 From: Jean-Pierre Busch Date: Wed, 7 Jun 2023 18:02:37 +0200 Subject: [PATCH 149/159] add "About" section to README --- README.md | 11 ++++++++++- 1 file changed, 10 insertions(+), 1 deletion(-) diff --git a/README.md b/README.md index cee944b..09bd0d2 100644 --- a/README.md +++ b/README.md @@ -31,7 +31,16 @@ We recommend to use *docker-ros* in combination with our other tools for Docker ## About -... TODO ... +*docker-ros* provides a generic [Dockerfile](docker/Dockerfile) that can be used to build development and deployment Docker images for arbitrary ROS packages or package stacks. It also provides CI configurations for GitHub and GitLab ([GitHub action](action.yml) / [GitLab CI template](templates/.gitlab-ci.template.yml)), which automatically builds these Docker images. The development image contains all required dependencies and the source code of your ROS-based repository. The deployment image only contains dependencies and the compiled binaries created by building the ROS packages in the repository. + +The Dockerfile performs the following steps to automatically build these images: +1. All dependency repositories that are defined in a `.repos` file anywhere in the repository are cloned using [vcstool](https://github.com/dirk-thomas/vcstool). +1. The ROS dependencies listed in each package's `package.xml` are installed by [rosdep](https://docs.ros.org/en/independent/api/rosdep/html/). +1. *(optional)* Additional dependencies from a special file `additional.apt-dependencies` are installed, if needed (see [advanced dependencies](#extra-system-dependencies-apt)). +1. *(optional)* A special folder `files/` is copied into the images, if needed (see [advanced dependencies](#extra-image-files)). +1. *(optional)* A special script `custom.sh` is executed to perform further arbitrary installation commands, if needed (see [advanced dependencies](#custom-installation-script)). +1. *(deployment)* All ROS packages are built using `catkin` (ROS) or `colcon` (ROS2). +1. *(deployment)* A custom launch command is configured to run on container start. ### Prerequisites From 90b7eb317ef718168ede37475ad854ecbd7921fa Mon Sep 17 00:00:00 2001 From: Jean-Pierre Busch Date: Wed, 7 Jun 2023 18:03:10 +0200 Subject: [PATCH 150/159] add "advanced dependencies" section to README --- README.md | 13 +++++++++---- 1 file changed, 9 insertions(+), 4 deletions(-) diff --git a/README.md b/README.md index 09bd0d2..9609c8a 100644 --- a/README.md +++ b/README.md @@ -219,20 +219,25 @@ jobs: ## Advanced Dependencies -... TODO ... +For a better overview we recommend to place all *docker-ros* related files in a `docker` folder on top repository level. ### Extra System Dependencies (apt) -... TODO ... +If your ROS-based repository requires system dependencies that cannot be installed by specifying their [rosdep](https://docs.ros.org/en/independent/api/rosdep/html/) keys in a `package.xml`, you can use the special `additional.apt-dependencies` file. + +Create a file `additional.apt-dependencies` in your `docker` folder and list any other dependencies that need to be installed via apt. ### Custom Installation Script -... TODO ... +If your ROS-based repository requires to execute any other installation or pre-/post-installation steps, you can use the special `custom.sh` script. + +Create a script `custom.sh` in your `docker` folder that executes arbitrary commands as part of the image building process. ### Extra Image Files -... TODO ... +If you need to have additional files present in the deployment image, you can use the special `files` folder. These will be copied into the container before the custom installation script `custom.sh` is executed. +Create a folder `files` in your `docker` folder and place any files or directories in it. The contents will be copied to `/docker-ros/files` in the image. ## Configuration Variables From c5fc53f83ff2d8ebaa37522ed8e4234d912d8d2a Mon Sep 17 00:00:00 2001 From: Jean-Pierre Busch Date: Wed, 7 Jun 2023 18:13:33 +0200 Subject: [PATCH 151/159] add "local build" section to README --- README.md | 23 ++++++++++++++++++++--- 1 file changed, 20 insertions(+), 3 deletions(-) diff --git a/README.md b/README.md index 9609c8a..28c6d64 100644 --- a/README.md +++ b/README.md @@ -214,9 +214,26 @@ jobs: ### Build images locally -... TODO ... - - +To build docker images locally using *docker-ros*, you have to follow these instructions: + +1. For a better overview we recommend to place all docker-ros related files in a docker folder on top repository level. So first, if not done yet, add a `docker` folder to your repository. + ```bash + # ros-repository/ + mkdir docker + ``` +2. Clone *docker-ros* as submodule to `docker/docker-ros`. + ```bash + # ros-repository/ + git submodule add git@github.com:ika-rwth-aachen/docker-ros.git docker/docker-ros + ``` +3. Run `build.sh` with desired configuration. The build can be configured by the same [environment variables](#configuration-variables) as the GitLab CI. Minimal example: + ```bash + # ros-repository/ + cd docker + BASE_IMAGE=rwthika/ros2:humble IMAGE=my_minimal_image:latest ./docker-ros/scripts/build.sh + ``` +> **Note:** +> You can save you desired environment variables in an `.env` file and soure it before running the build script. In this case the variables do not have to be written into the cli. ## Advanced Dependencies For a better overview we recommend to place all *docker-ros* related files in a `docker` folder on top repository level. From a782c0aa12759bc524ab463719be94f753becf7d Mon Sep 17 00:00:00 2001 From: Lennart Reiher Date: Thu, 8 Jun 2023 00:11:13 +0200 Subject: [PATCH 152/159] finish missing parts in readme --- README.md | 83 +++++++++++++++++++++++++++++++++++++++---------------- 1 file changed, 59 insertions(+), 24 deletions(-) diff --git a/README.md b/README.md index 28c6d64..c21d9ec 100644 --- a/README.md +++ b/README.md @@ -31,25 +31,58 @@ We recommend to use *docker-ros* in combination with our other tools for Docker ## About -*docker-ros* provides a generic [Dockerfile](docker/Dockerfile) that can be used to build development and deployment Docker images for arbitrary ROS packages or package stacks. It also provides CI configurations for GitHub and GitLab ([GitHub action](action.yml) / [GitLab CI template](templates/.gitlab-ci.template.yml)), which automatically builds these Docker images. The development image contains all required dependencies and the source code of your ROS-based repository. The deployment image only contains dependencies and the compiled binaries created by building the ROS packages in the repository. +*docker-ros* provides a generic [Dockerfile](docker/Dockerfile) that can be used to build development and deployment Docker images for arbitrary ROS packages or package stacks. Building such images can easily be automated by integrating *docker-ros* into CI through the provided [GitHub action](action.yml) or [GitLab CI template](templates/.gitlab-ci.template.yml). The development image built by *docker-ros* contains all required dependencies and the source code of your ROS-based repository. The deployment image only contains dependencies and the compiled binaries created by building the ROS packages in the repository. *docker-ros* is also able to build multi-arch Docker images for *amd64* and *arm64* architectures. -The Dockerfile performs the following steps to automatically build these images: -1. All dependency repositories that are defined in a `.repos` file anywhere in the repository are cloned using [vcstool](https://github.com/dirk-thomas/vcstool). -1. The ROS dependencies listed in each package's `package.xml` are installed by [rosdep](https://docs.ros.org/en/independent/api/rosdep/html/). -1. *(optional)* Additional dependencies from a special file `additional.apt-dependencies` are installed, if needed (see [advanced dependencies](#extra-system-dependencies-apt)). -1. *(optional)* A special folder `files/` is copied into the images, if needed (see [advanced dependencies](#extra-image-files)). -1. *(optional)* A special script `custom.sh` is executed to perform further arbitrary installation commands, if needed (see [advanced dependencies](#custom-installation-script)). -1. *(deployment)* All ROS packages are built using `catkin` (ROS) or `colcon` (ROS2). -1. *(deployment)* A custom launch command is configured to run on container start. +The Dockerfile performs the following steps to build these images: +1. All dependency repositories that are defined in a `.repos` file anywhere in the repository are cloned using [*vcstool*](https://github.com/dirk-thomas/vcstool). +2. The ROS dependencies listed in each package's `package.xml` are installed by [*rosdep*](https://docs.ros.org/en/independent/api/rosdep/html/). +3. *(optional)* Additional dependencies from a special file `additional.apt-dependencies` are installed, if needed (see [*Advanced Dependencies*](#extra-system-dependencies-apt)). +4. *(optional)* A special folder `files/` is copied into the images, if needed (see [*Advanced Dependencies*](#extra-image-files)). +5. *(optional)* A special script `custom.sh` is executed to perform further arbitrary installation commands, if needed (see [*Advanced Dependencies*](#custom-installation-script)). +6. *(deployment)* All ROS packages are built using `catkin` (ROS) or `colcon` (ROS2). +7. *(deployment)* A custom launch command is configured to run on container start. ### Prerequisites -... TODO ... +*docker-ros* is made for automated execution in GitHub or GitLab CI pipelines. For local execution, see [*Build images locally*](#build-images-locally). + +
GitHub + +GitHub offers free minutes on GitHub-hosted runners executing GitHub Actions, [see here](https://docs.github.com/en/billing/managing-billing-for-github-actions/about-billing-for-github-actions). No further setup is required other than integrating *docker-ros* into your repository, see [*Usage*](#usage). + +Note that GitHub is currently only offering Linux runners based on the *amd64* architecture. *docker-ros* can also build multi-arch Docker images solely on the *amd64* platform through emulation, but performance can be improved greatly by deploying [self-hosted runners](https://docs.github.com/en/actions/hosting-your-own-runners/managing-self-hosted-runners/about-self-hosted-runners) for the *arm64* platform. + +
+ +
GitLab + +> **Note** +> - GitLab runners must be based on the Docker executor, [see here](https://docs.gitlab.com/runner/executors/docker.html) +> - GitLab runners must run in privileged mode for Docker-in-Docker, [see here](https://docs.gitlab.com/runner/executors/docker.html#use-docker-in-docker-with-privileged-mode) +> - GitLab runners must be tagged with tags `privileged` and either `amd64` or `arm64` depending on their architecture + +GitLab offers free minutes on GitLab-hosted runners executing GitLab CI pipelines on [gitlab.com](https://gitlab.com), [see here](https://docs.gitlab.com/runner/#use-gitlabcom-saas-runners). On self-hosted GitLab instances, you can set up self-hosted runners, [see here](https://docs.gitlab.com/runner/#use-self-managed-runners). + +Note that GitLab is currently only offering Linux runners based on the *amd64* architecture. *docker-ros* can also build multi-arch Docker images solely on the *amd64* platform through emulation, but performance can be improved greatly by deploying [self-hosted runners](https://docs.gitlab.com/runner/#use-self-managed-runners) for the *arm64* platform. + +
## Usage -... TODO ... +*docker-ros* can easily be integrated into any GitHub or GitLab repository containing ROS packages. For local execution, see [*Build images locally*](#build-images-locally). + +
GitHub + +*docker-ros* provides a [GitHub action](action.yml) that can simply be added to a job via the [`jobs..steps[*].uses` keyword](https://docs.github.com/en/actions/using-workflows/workflow-syntax-for-github-actions#jobsjob_idstepsuses). A quick start for GitHub Actions is found [here](https://docs.github.com/en/actions/quickstart). + +
+ +
GitLab + +*docker-ros* provides a [GitLab CI template](templates/.gitlab-ci.template.yml) that can simply be included in a [`.gitlab-ci.yml`](https://docs.gitlab.com/ee/ci/yaml/gitlab_ci_yaml.html) file. A quick start for GitLab CI is found [here](https://docs.gitlab.com/ee/ci/quick_start/). + +
### Build a minimal image for deployment @@ -214,29 +247,30 @@ jobs: ### Build images locally -To build docker images locally using *docker-ros*, you have to follow these instructions: +*docker-ros* can build Docker images locally by executing the [`build.sh`](scripts/build.sh) script. -1. For a better overview we recommend to place all docker-ros related files in a docker folder on top repository level. So first, if not done yet, add a `docker` folder to your repository. - ```bash - # ros-repository/ - mkdir docker - ``` -2. Clone *docker-ros* as submodule to `docker/docker-ros`. +1. Clone *docker-ros* as a Git submodule to `docker/docker-ros` in your repository. ```bash # ros-repository/ - git submodule add git@github.com:ika-rwth-aachen/docker-ros.git docker/docker-ros + mkdir -p docker + git submodule add https://github.com/ika-rwth-aachen/docker-ros.git docker/docker-ros ``` -3. Run `build.sh` with desired configuration. The build can be configured by the same [environment variables](#configuration-variables) as the GitLab CI. Minimal example: +2. Configure the build using the same [environment variables](#configuration-variables) as used for GitLab CI and run [`build.sh`](scripts/build.sh), e.g.: ```bash # ros-repository/ cd docker - BASE_IMAGE=rwthika/ros2:humble IMAGE=my_minimal_image:latest ./docker-ros/scripts/build.sh + BASE_IMAGE="rwthika/ros2:humble" \ + COMMAND="ros2 run my_pkg my_node" \ + IMAGE="my-image:latest" \ + ./docker-ros/scripts/build.sh ``` -> **Note:** -> You can save you desired environment variables in an `.env` file and soure it before running the build script. In this case the variables do not have to be written into the cli. + > **Note** + > You can save your environment variable configuration in a `.env` file and source it before running the build script. + + ## Advanced Dependencies -For a better overview we recommend to place all *docker-ros* related files in a `docker` folder on top repository level. +In order to keep things organized, we recommend to place all *docker-ros* related files in a `docker` folder on top repository level. ### Extra System Dependencies (apt) @@ -256,6 +290,7 @@ If you need to have additional files present in the deployment image, you can us Create a folder `files` in your `docker` folder and place any files or directories in it. The contents will be copied to `/docker-ros/files` in the image. + ## Configuration Variables > **Note** From 4bc73c3e549ef52578218d1c4b3029764e63ec7f Mon Sep 17 00:00:00 2001 From: Jean-Pierre Busch Date: Thu, 8 Jun 2023 12:17:32 +0200 Subject: [PATCH 153/159] unify variable names --- README.md | 35 +++++++++++++++---------------- action.yml | 4 ++-- templates/.gitlab-ci.template.yml | 6 +++--- 3 files changed, 22 insertions(+), 23 deletions(-) diff --git a/README.md b/README.md index 068fcd8..479c52f 100644 --- a/README.md +++ b/README.md @@ -9,21 +9,20 @@ *docker-ros* automatically builds minimal container images of ROS applications. -- [*docker-ros* – Automated Containerization of ROS Applications](#docker-ros--automated-containerization-of-ros-applications) - - [About](#about) - - [Prerequisites](#prerequisites) - - [Usage](#usage) - - [Build a minimal image for deployment](#build-a-minimal-image-for-deployment) - - [Build development and deployment images](#build-development-and-deployment-images) - - [Build multi-arch images](#build-multi-arch-images) - - [Build deployment image with additional industrial\_ci check](#build-deployment-image-with-additional-industrial_ci-check) - - [Build multi-arch images on arch-specific self-hosted runners in parallel](#build-multi-arch-images-on-arch-specific-self-hosted-runners-in-parallel) - - [Build images locally](#build-images-locally) - - [Advanced Dependencies](#advanced-dependencies) - - [Extra System Dependencies (apt)](#extra-system-dependencies-apt) - - [Custom Installation Script](#custom-installation-script) - - [Extra Image Files](#extra-image-files) - - [Configuration Variables](#configuration-variables) +- [About](#about) + - [Prerequisites](#prerequisites) +- [Usage](#usage) + - [Build a minimal image for deployment](#build-a-minimal-image-for-deployment) + - [Build development and deployment images](#build-development-and-deployment-images) + - [Build multi-arch images](#build-multi-arch-images) + - [Build deployment image with additional industrial\_ci check](#build-deployment-image-with-additional-industrial_ci-check) + - [Build multi-arch images on arch-specific self-hosted runners in parallel](#build-multi-arch-images-on-arch-specific-self-hosted-runners-in-parallel) + - [Build images locally](#build-images-locally) +- [Advanced Dependencies](#advanced-dependencies) + - [Extra System Dependencies (apt)](#extra-system-dependencies-apt) + - [Custom Installation Script](#custom-installation-script) + - [Extra Image Files](#extra-image-files) +- [Configuration Variables](#configuration-variables) We recommend to use *docker-ros* in combination with our other tools for Docker and ROS. - [*docker-ros-ml-images*](https://github.com/ika-rwth-aachen/docker-ros-ml-images) provides machine learning-enabled ROS Docker images @@ -318,6 +317,9 @@ Create a folder `files` in your `docker` folder and place any files or directori - **`enable-industrial-ci` | `ENABLE_INDUSTRIAL_CI`** Enable [*industrial_ci*](https://github.com/ros-industrial/industrial_ci) *default:* `false` +- **`enable-push-as-latest` | `ENABLE_PUSH_AS_LATEST`** + Push images with tag `latest`/`latest-dev` in addition to the configured image names + *default:* `false` - **`enable-singlearch-push` | `ENABLE_SINGLEARCH_PUSH`** Enable push of single arch images with `-amd64`/`-arm64` postfix *default:* `false` @@ -344,9 +346,6 @@ Create a folder `files` in your `docker` folder and place any files or directori Target platform architecture (comma-separated list) *default:* runner architecture *supported values:* `amd64`, `arm64` -- **`push-as-latest` | `PUSH_AS_LATEST`** - Push images with tag `latest`/`latest-dev` in addition to the configured image names - *default:* `false` - **`registry-password` | `REGISTRY_PASSWORD`** Docker registry password *default:* `${{ github.token }}` | `$CI_REGISTRY_PASSWORD` diff --git a/action.yml b/action.yml index 5b43bcc..0507066 100644 --- a/action.yml +++ b/action.yml @@ -73,7 +73,7 @@ inputs: description: "Enable push of single arch images with [-amd64|-arm64] postfix" default: false - push-as-latest: + enable-push-as-latest: description: "Push images with tag `latest`/`latest-dev` in addition to the configured image names" default: false @@ -184,7 +184,7 @@ runs: _IMAGE_POSTFIX: ${{ github.ref != format('refs/heads/{0}', github.event.repository.default_branch) && format('_{0}_ci', steps.slugify-ref-name.outputs.slug) || '' }} - name: Push images (as latest) - if: ${{ inputs.push-as-latest == 'true' }} + if: ${{ inputs.enable-push-as-latest == 'true' }} shell: bash working-directory: ${{ inputs.build-context }} run: docker/docker-ros/scripts/ci.sh diff --git a/templates/.gitlab-ci.template.yml b/templates/.gitlab-ci.template.yml index e9646ab..6376adf 100644 --- a/templates/.gitlab-ci.template.yml +++ b/templates/.gitlab-ci.template.yml @@ -23,7 +23,7 @@ variables: REGISTRY_PASSWORD: ${CI_REGISTRY_PASSWORD} # Docker registry password ENABLE_INDUSTRIAL_CI: 'false' # Enable industrial_ci ENABLE_SINGLEARCH_PUSH: 'false' # Enable push of single arch images with [-amd64|-arm64] postfix - PUSH_AS_LATEST: 'false' # Push images with tag `latest`/`latest-dev` in addition to the configured image names + ENABLE_PUSH_AS_LATEST: 'false' # Push images with tag `latest`/`latest-dev` in addition to the configured image names GIT_HTTPS_SERVER: ${CI_SERVER_HOST} # Server URL (without protocol) for cloning private Git repositories via HTTPS GIT_HTTPS_USER: gitlab-ci-token # Username for cloning private Git repositories via HTTPS GIT_HTTPS_PASSWORD: ${CI_JOB_TOKEN} # Password for cloning private Git repositories via HTTPS @@ -263,7 +263,7 @@ Push latest: extends: .push rules: - !reference [.push, rules] - - if: $CI_COMMIT_BRANCH == $CI_DEFAULT_BRANCH && $PUSH_AS_LATEST == 'true' + - if: $CI_COMMIT_BRANCH == $CI_DEFAULT_BRANCH && $ENABLE_PUSH_AS_LATEST == 'true' variables: IMG_DEV: ${_IMAGE_DEV_LATEST} IMG_RUN: ${_IMAGE_RUN_LATEST} @@ -283,7 +283,7 @@ Push tag: extends: .push rules: - !reference [.push, rules] - - if: $CI_COMMIT_TAG && $PUSH_AS_LATEST == 'true' + - if: $CI_COMMIT_TAG && $ENABLE_PUSH_AS_LATEST == 'true' variables: IMG_DEV: ${_IMAGE_DEV_TAG} IMG_RUN: ${_IMAGE_RUN_TAG} From e878312b04651a676e4a16293456a6ad7c3e9d0e Mon Sep 17 00:00:00 2001 From: Jean-Pierre Busch Date: Thu, 8 Jun 2023 12:23:42 +0200 Subject: [PATCH 154/159] also setup docker-ros for gitlab test stage --- templates/.gitlab-ci.template.yml | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/templates/.gitlab-ci.template.yml b/templates/.gitlab-ci.template.yml index 6376adf..2b64fb2 100644 --- a/templates/.gitlab-ci.template.yml +++ b/templates/.gitlab-ci.template.yml @@ -68,7 +68,7 @@ default: tags: - privileged - amd64 - before_script: + before_script: &default_before_script - echo -e "section_start:`date +%s`:setup_section[collapsed=true]\r\e[0KSetup docker-ros" - apk add bash - cd ${BUILD_CONTEXT} @@ -163,14 +163,14 @@ run-arm64: AFTER_INIT_EMBED: git config --global url.https://${GIT_HTTPS_USER}:${GIT_HTTPS_PASSWORD}@${GIT_HTTPS_SERVER}.insteadOf https://${GIT_HTTPS_SERVER} DOCKER_RUN_OPTS: -u root:root before_script: + - *default_before_script - |- if [[ ${CI_RUNNER_EXECUTABLE_ARCH} != ${_PLATFORM} && ${CI_RUNNER_EXECUTABLE_ARCH} != linux/${_PLATFORM} ]]; then docker run --rm --privileged multiarch/qemu-user-static --reset -p yes fi - - docker login -u ${REGISTRY_USERNAME} -p ${REGISTRY_PASSWORD} ${REGISTRY} - apk add --update bash coreutils grep tar python3 py3-pip - pip install vcstool - - UPSTREAM_WORKSPACE=$(python3 ${BUILD_CONTEXT}/docker/docker-ros/recursive_vcs_import.py ${BUILD_CONTEXT} | tail -1) + - UPSTREAM_WORKSPACE=$(python3 ${BUILD_CONTEXT}/docker/docker-ros/docker/recursive_vcs_import.py ${BUILD_CONTEXT} | tail -1) - if [ -z "${UPSTREAM_WORKSPACE}" ]; then echo "repositories:" > ${BUILD_CONTEXT}/.repos; UPSTREAM_WORKSPACE=${BUILD_CONTEXT}/.repos; fi - echo ${UPSTREAM_WORKSPACE} - export UPSTREAM_WORKSPACE From 75f012481529b528ba685f7d4c1568141d79e725 Mon Sep 17 00:00:00 2001 From: Lennart Reiher Date: Thu, 8 Jun 2023 13:46:05 +0200 Subject: [PATCH 155/159] revert parts of gitlab !39 for now to be re-added for gitlab and github together with !42 --- templates/.gitlab-ci.template.yml | 13 +++++-------- 1 file changed, 5 insertions(+), 8 deletions(-) diff --git a/templates/.gitlab-ci.template.yml b/templates/.gitlab-ci.template.yml index 2b64fb2..3955635 100644 --- a/templates/.gitlab-ci.template.yml +++ b/templates/.gitlab-ci.template.yml @@ -68,7 +68,7 @@ default: tags: - privileged - amd64 - before_script: &default_before_script + before_script: - echo -e "section_start:`date +%s`:setup_section[collapsed=true]\r\e[0KSetup docker-ros" - apk add bash - cd ${BUILD_CONTEXT} @@ -158,23 +158,20 @@ run-arm64: .test: variables: + UPSTREAM_WORKSPACE: ${BUILD_CONTEXT}/.repos TARGET_WORKSPACE: ${BUILD_CONTEXT} ADDITIONAL_DEBS: git AFTER_INIT_EMBED: git config --global url.https://${GIT_HTTPS_USER}:${GIT_HTTPS_PASSWORD}@${GIT_HTTPS_SERVER}.insteadOf https://${GIT_HTTPS_SERVER} DOCKER_RUN_OPTS: -u root:root before_script: - - *default_before_script + - docker login -u ${REGISTRY_USERNAME} -p ${REGISTRY_PASSWORD} ${REGISTRY} + - apk add --update bash coreutils grep tar - |- if [[ ${CI_RUNNER_EXECUTABLE_ARCH} != ${_PLATFORM} && ${CI_RUNNER_EXECUTABLE_ARCH} != linux/${_PLATFORM} ]]; then docker run --rm --privileged multiarch/qemu-user-static --reset -p yes fi - - apk add --update bash coreutils grep tar python3 py3-pip - - pip install vcstool - - UPSTREAM_WORKSPACE=$(python3 ${BUILD_CONTEXT}/docker/docker-ros/docker/recursive_vcs_import.py ${BUILD_CONTEXT} | tail -1) - - if [ -z "${UPSTREAM_WORKSPACE}" ]; then echo "repositories:" > ${BUILD_CONTEXT}/.repos; UPSTREAM_WORKSPACE=${BUILD_CONTEXT}/.repos; fi - - echo ${UPSTREAM_WORKSPACE} - - export UPSTREAM_WORKSPACE - git clone --branch master --depth 1 https://github.com/ros-industrial/industrial_ci.git .industrial_ci + - test -f ${BUILD_CONTEXT}/.repos || echo "repositories:" > ${BUILD_CONTEXT}/.repos script: .industrial_ci/gitlab.sh Test dev-amd64: From c02c713783060683daf3b8ea8c8b4b7b4d7d3e88 Mon Sep 17 00:00:00 2001 From: Lennart Reiher Date: Thu, 8 Jun 2023 14:06:33 +0200 Subject: [PATCH 156/159] add missing logo to readme --- README.md | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/README.md b/README.md index 479c52f..40a752f 100644 --- a/README.md +++ b/README.md @@ -1,4 +1,4 @@ -# *docker-ros* – Automated Containerization of ROS Applications +# *docker-ros* – Automated Containerization of ROS Apps

@@ -9,6 +9,8 @@ *docker-ros* automatically builds minimal container images of ROS applications. + + - [About](#about) - [Prerequisites](#prerequisites) - [Usage](#usage) From 85af89d3cdd149924e1f7a1b157743f0bb8a1ac9 Mon Sep 17 00:00:00 2001 From: Lennart Reiher Date: Thu, 8 Jun 2023 14:09:26 +0200 Subject: [PATCH 157/159] improve log groups --- scripts/utils.sh | 12 ++++++------ templates/.gitlab-ci.template.yml | 8 ++++---- 2 files changed, 10 insertions(+), 10 deletions(-) diff --git a/scripts/utils.sh b/scripts/utils.sh index 0caa07b..9eee182 100644 --- a/scripts/utils.sh +++ b/scripts/utils.sh @@ -8,17 +8,17 @@ require_var() { } open_log_group() { - if [[ "${GITLAB_CI}" ]]; then - echo -e "section_start:`date +%s`:my_first_section[collapsed=true]\r\e[0K${1}" - elif [[ "${CI}" ]]; then + if [[ -n "${GITLAB_CI}" ]]; then + echo -e "section_start:`date +%s`:section[collapsed=true]\r\e[0K[docker-ros] ${1}" + elif [[ -n "${GITHUB_ACTIONS}" ]]; then echo "::group::[docker-ros] ${1}" fi } close_log_group() { - if [[ "${GITLAB_CI}" ]]; then - echo -e "section_end:`date +%s`:my_first_section\r\e[0K" - elif [[ "${CI}" ]]; then + if [[ -n "${GITLAB_CI}" ]]; then + echo -e "section_end:`date +%s`:section\r\e[0K" + elif [[ -n "${GITHUB_ACTIONS}" ]]; then echo "::endgroup::" fi } diff --git a/templates/.gitlab-ci.template.yml b/templates/.gitlab-ci.template.yml index 3955635..df3c81c 100644 --- a/templates/.gitlab-ci.template.yml +++ b/templates/.gitlab-ci.template.yml @@ -69,7 +69,7 @@ default: - privileged - amd64 before_script: - - echo -e "section_start:`date +%s`:setup_section[collapsed=true]\r\e[0KSetup docker-ros" + - echo -e "section_start:`date +%s`:section[collapsed=true]\r\e[0K[docker-ros] Setup docker-ros" - apk add bash - cd ${BUILD_CONTEXT} - |- @@ -84,7 +84,7 @@ default: - docker login -u ${REGISTRY_USERNAME} -p ${REGISTRY_PASSWORD} ${REGISTRY} - docker context create buildx-context - docker buildx create --use buildx-context - - echo -e "section_end:`date +%s`:setup_section\r\e[0K" + - echo -e "section_end:`date +%s`:section\r\e[0K" .build: script: @@ -93,9 +93,9 @@ default: docker run --rm --privileged multiarch/qemu-user-static --reset -p yes fi - TARGET=${_TARGET} PLATFORM=${_PLATFORM} ./docker/docker-ros/scripts/ci.sh - - echo -e "section_start:`date +%s`:push_section[collapsed=true]\r\e[0KPush ${IMAGE}" + - echo -e "section_start:`date +%s`:section[collapsed=true]\r\e[0K[docker-ros] Push ${IMAGE}" - docker push ${IMAGE} - - echo -e "section_end:`date +%s`:push_section\r\e[0K" + - echo -e "section_end:`date +%s`:section\r\e[0K" dev-amd64: stage: Build dev Images From 151b4ca79023ec5a8138a16fd4606568979fee32 Mon Sep 17 00:00:00 2001 From: Lennart Reiher Date: Thu, 8 Jun 2023 14:23:28 +0200 Subject: [PATCH 158/159] move gitlab-ci template --- .../docker-ros.yml | 0 README.md | 12 ++++++------ 2 files changed, 6 insertions(+), 6 deletions(-) rename templates/.gitlab-ci.template.yml => .gitlab-ci/docker-ros.yml (100%) diff --git a/templates/.gitlab-ci.template.yml b/.gitlab-ci/docker-ros.yml similarity index 100% rename from templates/.gitlab-ci.template.yml rename to .gitlab-ci/docker-ros.yml diff --git a/README.md b/README.md index 40a752f..77ad281 100644 --- a/README.md +++ b/README.md @@ -33,7 +33,7 @@ We recommend to use *docker-ros* in combination with our other tools for Docker ## About -*docker-ros* provides a generic [Dockerfile](docker/Dockerfile) that can be used to build development and deployment Docker images for arbitrary ROS packages or package stacks. Building such images can easily be automated by integrating *docker-ros* into CI through the provided [GitHub action](action.yml) or [GitLab CI template](templates/.gitlab-ci.template.yml). The development image built by *docker-ros* contains all required dependencies and the source code of your ROS-based repository. The deployment image only contains dependencies and the compiled binaries created by building the ROS packages in the repository. *docker-ros* is also able to build multi-arch Docker images for *amd64* and *arm64* architectures. +*docker-ros* provides a generic [Dockerfile](docker/Dockerfile) that can be used to build development and deployment Docker images for arbitrary ROS packages or package stacks. Building such images can easily be automated by integrating *docker-ros* into CI through the provided [GitHub action](action.yml) or [GitLab CI template](.gitlab-ci/docker-ros.yml). The development image built by *docker-ros* contains all required dependencies and the source code of your ROS-based repository. The deployment image only contains dependencies and the compiled binaries created by building the ROS packages in the repository. *docker-ros* is also able to build multi-arch Docker images for *amd64* and *arm64* architectures. The Dockerfile performs the following steps to build these images: 1. All dependency repositories that are defined in a `.repos` file anywhere in the repository are cloned using [*vcstool*](https://github.com/dirk-thomas/vcstool). @@ -82,7 +82,7 @@ Note that GitLab is currently only offering Linux runners based on the *amd64* a

GitLab -*docker-ros* provides a [GitLab CI template](templates/.gitlab-ci.template.yml) that can simply be included in a [`.gitlab-ci.yml`](https://docs.gitlab.com/ee/ci/yaml/gitlab_ci_yaml.html) file. A quick start for GitLab CI is found [here](https://docs.gitlab.com/ee/ci/quick_start/). +*docker-ros* provides a [GitLab CI template](.gitlab-ci/docker-ros.yml) that can simply be included in a [`.gitlab-ci.yml`](https://docs.gitlab.com/ee/ci/yaml/gitlab_ci_yaml.html) file. A quick start for GitLab CI is found [here](https://docs.gitlab.com/ee/ci/quick_start/).
@@ -107,7 +107,7 @@ jobs: ```yml include: - - remote: https://raw.githubusercontent.com/ika-rwth-aachen/docker-ros/main/templates/.gitlab-ci.template.yml + - remote: https://raw.githubusercontent.com/ika-rwth-aachen/docker-ros/main/.gitlab-ci/docker-ros.yml variables: BASE_IMAGE: rwthika/ros2:humble @@ -138,7 +138,7 @@ jobs: ```yml include: - - remote: https://raw.githubusercontent.com/ika-rwth-aachen/docker-ros/main/templates/.gitlab-ci.template.yml + - remote: https://raw.githubusercontent.com/ika-rwth-aachen/docker-ros/main/.gitlab-ci/docker-ros.yml variables: BASE_IMAGE: rwthika/ros2:humble @@ -171,7 +171,7 @@ jobs: ```yml include: - - remote: https://raw.githubusercontent.com/ika-rwth-aachen/docker-ros/main/templates/.gitlab-ci.template.yml + - remote: https://raw.githubusercontent.com/ika-rwth-aachen/docker-ros/main/.gitlab-ci/docker-ros.yml variables: BASE_IMAGE: rwthika/ros2:humble @@ -204,7 +204,7 @@ jobs: ```yml include: - - remote: https://raw.githubusercontent.com/ika-rwth-aachen/docker-ros/main/templates/.gitlab-ci.template.yml + - remote: https://raw.githubusercontent.com/ika-rwth-aachen/docker-ros/main/.gitlab-ci/docker-ros.yml variables: BASE_IMAGE: rwthika/ros2:humble From 999b92cca7c3a9d8d0aa38adc724d83f4f0342b6 Mon Sep 17 00:00:00 2001 From: Lennart Reiher Date: Thu, 8 Jun 2023 14:31:42 +0200 Subject: [PATCH 159/159] add template compose file for building --- templates/docker-compose.template.yml | 30 +++++++++++++++++++++++++++ 1 file changed, 30 insertions(+) create mode 100644 templates/docker-compose.template.yml diff --git a/templates/docker-compose.template.yml b/templates/docker-compose.template.yml new file mode 100644 index 0000000..3a122e2 --- /dev/null +++ b/templates/docker-compose.template.yml @@ -0,0 +1,30 @@ +x-base-image: &base-image BASE_IMAGE # e.g. rwthika/ros2:humble +x-dev-image: &dev-image DEV_IMAGE # e.g. my-image:latest-dev +x-run-image: &run-image RUN_IMAGE # e.g. my-image:latest +x-command: &command COMMAND # e.g. ros2 run my_pkg my_node + +# ============================================================================== + +x-build: &build + dockerfile: ./docker/docker-ros/docker/Dockerfile + context: ../ + args: + BASE_IMAGE: *base-image + COMMAND: *command + GIT_HTTPS_SERVER: $GIT_HTTPS_SERVER + GIT_HTTPS_USER: $GIT_HTTPS_USER + GIT_HTTPS_PASSWORD: $GIT_HTTPS_PASSWORD + GIT_SSH_PRIVATE_KEY: $GIT_SSH_PRIVATE_KEY + GIT_SSH_KNOWN_HOST_KEYS: $GIT_SSH_KNOWN_HOST_KEYS + +services: + dev: + image: *dev-image + build: + target: dev + <<: *build + run: + image: *run-image + build: + target: run + <<: *build