Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

feat: (reverts #108) full ros2-ws Dockerfile with fixed SHA256 for ros:iron #109

Merged
merged 8 commits into from
May 13, 2024
17 changes: 15 additions & 2 deletions .github/workflows/reusable-build-push.yml
Original file line number Diff line number Diff line change
Expand Up @@ -69,11 +69,24 @@ jobs:
run: |
BUILD_FLAGS=()

BASE_TAG=${{ inputs.ros_distro }}
ROS_DISTRO=${{ inputs.ros_distro }}
BUILD_FLAGS+=(--build-arg ROS_DISTRO=${ROS_DISTRO})

if [ ${ROS_DISTRO} == iron ]; then
# use a specific SHA256 digest for repeatability
# -> ros:iron from September 02, 2023
BASE_IMAGE=docker.io/library/ros@sha256
BASE_TAG=6df9b084cb7e918455df628126b2b647d2ad2e4b0e979fb8fbc525a610573bbb
else
BASE_IMAGE=docker.io/library/ros
BASE_TAG=${ROS_DISTRO}
fi

BUILD_FLAGS+=(--build-arg BASE_IMAGE=${BASE_IMAGE})
BUILD_FLAGS+=(--build-arg BASE_TAG=${BASE_TAG})

VERSION_TAG="v${{ needs.check-version.outputs.version }}"
IMAGE_TAGS="${VERSION_TAG},${VERSION_TAG}-${{ inputs.ros_distro}}","${{ inputs.ros_distro}}"
IMAGE_TAGS="${VERSION_TAG},${VERSION_TAG}-${ROS_DISTRO}","${ROS_DISTRO}"
GIT_TAG="${VERSION_TAG}-${{ inputs.ros_distro}}"
BUILD_FLAGS+=(--build-arg VERSION=${GIT_TAG})

Expand Down
154 changes: 150 additions & 4 deletions ros2_ws/Dockerfile
Original file line number Diff line number Diff line change
@@ -1,10 +1,156 @@
ARG BASE_IMAGE=docker.io/library/ros
ARG BASE_TAG=iron
FROM ghcr.io/aica-technology/ros2-control:${BASE_TAG}
FROM ${BASE_IMAGE}:${BASE_TAG} as environment-variables
ENV DEBIAN_FRONTEND=noninteractive
ENV PYTHONWARNINGS=ignore:::setuptools.command.install,ignore:::setuptools.command.easy_install,ignore:::pkg_resources
ENV PIP_NO_CACHE_DIR 1
ENV USER ros2
ENV HOME /home/${USER}
ENV ROS2_WORKSPACE /home/${USER}/ros2_ws
ENV COLCON_HOME ${HOME}/.colcon
ENV COLCON_DEFAULTS_FILE ${COLCON_HOME}/defaults.yaml
ENV COLCON_WORKSPACE=${ROS2_WORKSPACE}
ENV LD_LIBRARY_PATH=$LD_LIBRARY_PATH:/usr/local/lib

ARG VERSION=v0.0.0

FROM environment-variables as base-dependencies

# disable suggested and recommended install
RUN apt-config dump | grep -we Recommends -e Suggests | sed s/1/0/ \
| sudo tee /etc/apt/apt.conf.d/999norecommend

# install base dependencies
RUN apt-get update && apt-get install --no-install-recommends -y \
autoconf \
automake \
curl \
featherpad \
gdb \
git \
iputils-ping \
libboost-all-dev \
libtool \
mesa-utils \
nano \
python3-pip \
ros-${ROS_DISTRO}-xacro \
ros-${ROS_DISTRO}-robot-state-publisher \
ros-${ROS_DISTRO}-rviz2 \
rsync \
software-properties-common \
ssh \
unzip \
wget \
&& rm -rf /var/lib/apt/lists/*

RUN echo "Set disable_coredump false" >> /etc/sudo.conf

# configure sshd server settings
RUN ( \
echo 'LogLevel DEBUG2'; \
echo 'PubkeyAuthentication yes'; \
echo 'Subsystem sftp /usr/lib/openssh/sftp-server'; \
) > /etc/ssh/sshd_config_development \
&& mkdir /run/sshd


FROM base-dependencies as base-workspace

# create and configure a new user
ARG UID=1000
ARG GID=1000
RUN addgroup --gid ${GID} ${USER}
RUN adduser --gecos "ROS2 User" --uid ${UID} --gid ${GID} ${USER} && yes | passwd ${USER}
RUN usermod -a -G dialout ${USER}
RUN echo "${USER} ALL=(ALL) NOPASSWD: ALL" > /etc/sudoers.d/99_aptget
RUN chmod 0440 /etc/sudoers.d/99_aptget && chown root:root /etc/sudoers.d/99_aptget

# configure sshd entrypoint to authorise the new user for ssh access and
# optionally update UID and GID when invoking the container with the entrypoint script
COPY ./config/sshd_entrypoint.sh /sshd_entrypoint.sh
RUN chmod 744 /sshd_entrypoint.sh

# crete user group with realtime permissions and add user to it
RUN groupadd -g 3719 realtime && usermod -aG realtime ${USER}
RUN echo "@realtime soft rtprio 99\n@realtime hard rtprio 99\n" > \
/etc/security/limits.d/realtime.conf

# configure colcon defaults and utilities
USER ${USER}
WORKDIR ${HOME}
RUN wget https://raw.githubusercontent.com/aica-technology/.github/v0.9.0/guidelines/.clang-format
RUN mkdir -p ${COLCON_HOME}
COPY --chown=${USER}:${USER} ./config/colcon ${COLCON_HOME}
RUN /bin/bash ${COLCON_HOME}/setup.sh

# build ROS workspace
RUN mkdir -p ${ROS2_WORKSPACE}/src
WORKDIR ${ROS2_WORKSPACE}
RUN rosdep update
RUN /bin/bash -c "source /opt/ros/${ROS_DISTRO}/setup.bash; colcon build --symlink-install"

# prepend the environment sourcing to bashrc (appending will fail for non-interactive sessions)
RUN echo "source /opt/ros/${ROS_DISTRO}/setup.bash; \
source ${ROS2_WORKSPACE}/install/setup.bash" | cat - ${HOME}/.bashrc > tmp && mv tmp ${HOME}/.bashrc
# enable colorized output from ros logging
RUN echo "export RCUTILS_COLORIZED_OUTPUT=1" >> ${HOME}/.bashrc

# create the credentials to be able to pull private repos using ssh
USER root
RUN mkdir /root/.ssh/ && ssh-keyscan github.com | tee -a /root/.ssh/known_hosts
RUN echo "session required pam_limits.so" | tee --append /etc/pam.d/common-session > /dev/null

FROM base-workspace as ros2-control-iron

RUN apt-get update && apt-get install --no-install-recommends -y \
doxygen \
librange-v3-dev \
python3-jinja2 \
python3-typeguard \
&& rm -rf /var/lib/apt/lists/*

# build as ROS user
USER ${USER}
WORKDIR ${ROS2_WORKSPACE}/src

RUN git clone -b 3.18.0 --depth 1 https://github.com/ros-controls/ros2_control.git
RUN git clone -b 3.14.0 --depth 1 https://github.com/ros-controls/ros2_controllers.git
# get additional interface dependencies manually
RUN git clone -b 5.0.0 --depth 1 https://github.com/ros-controls/control_msgs.git
RUN git clone -b 1.0.2 --depth 1 https://github.com/pal-robotics/backward_ros.git
RUN git clone -b 3.1.2 --depth 1 https://github.com/ros/diagnostics.git
RUN git clone -b 2.5.0 --depth 1 https://github.com/ros-controls/realtime_tools.git
RUN git clone -b 1.7.0 --depth 1 https://github.com/ros2/rcl_interfaces.git
RUN git clone -b 0.11.0 --depth 1 https://github.com/ros2/test_interface_files.git
RUN git clone -b 1.16.0 --depth 1 https://github.com/ros/angles.git
RUN git clone -b ros2 --depth 1 https://github.com/ros-drivers/ackermann_msgs.git
RUN git clone -b 0.3.3 --depth 1 https://github.com/PickNikRobotics/generate_parameter_library.git
RUN git clone -b 0.2.2 --depth 1 https://github.com/PickNikRobotics/RSL.git
RUN git clone -b 1.0.2 --depth 1 https://github.com/PickNikRobotics/cpp_polyfills.git
RUN git clone -b 3.1.0 --depth 1 https://github.com/ros-controls/control_toolbox.git
RUN git clone -b 0.1.0 --depth 1 https://github.com/ros-controls/kinematics_interface.git

WORKDIR ${ROS2_WORKSPACE}
RUN /bin/bash -c "source /opt/ros/${ROS_DISTRO}/setup.bash; colcon build"
RUN rm -rf ./src

ARG ROS_DISTRO=iron
FROM ros2-control-${ROS_DISTRO} as ros2-control

FROM environment-variables as final
COPY --from=ros2-control / /

# start as ROS user
USER ${USER}
WORKDIR ${ROS2_WORKSPACE}

# Metadata
ARG BASE_IMAGE=docker.io/library/ros
ARG BASE_TAG=iron
ARG VERSION=v0.0.0
LABEL org.opencontainers.image.title="AICA ROS 2 image"
LABEL org.opencontainers.image.description="AICA base ROS 2 image (includes ros2_control)"
LABEL org.opencontainers.image.version="${VERSION}"
LABEL org.opencontainers.image.base.name="docker.io/library/ros:${BASE_TAG}"
LABEL tech.aica.image.metadata='{"type":"base/ws","base":{"name":"docker.io/library/ros","version":"'${BASE_TAG}'"}}'
LABEL org.opencontainers.image.base.name="${BASE_IMAGE}:${BASE_TAG}"
LABEL tech.aica.image.metadata='{"type":"base/ws","base":{"name":"${BASE_IMAGE}:${BASE_TAG}","version":"${VERSION}"}}'
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

While the value is correct, the formatting isn't. The previous version used "'${VAR}'" for a specific reason (' strings do not extrapolate variables). This breaks the metadata, see:

                "tech.aica.image.metadata": "{\"type\":\"base/ws\",\"base\":{\"name\":\"${BASE_IMAGE}:${BASE_TAG}\",\"version\":\"${VERSION}\"}}"

LABEL devcontainer.metadata='[{"containerUser": "ros2"}]'
2 changes: 1 addition & 1 deletion ros2_ws/VERSION.iron
Original file line number Diff line number Diff line change
@@ -1 +1 @@
1.0.0
1.0.1