diff --git a/.devcontainer/linux/devcontainer.json b/.devcontainer/linux/devcontainer.json index 06451cd1..52f25cf0 100644 --- a/.devcontainer/linux/devcontainer.json +++ b/.devcontainer/linux/devcontainer.json @@ -6,13 +6,13 @@ }, "mounts": [ // SSH Keys - "type=bind,source=/home/${localEnv:USER}/.ssh,target=/root/.ssh,readonly", + "type=bind,source=/home/${localEnv:USER}/.ssh,target=/home/rov/.ssh,readonly", // X11 for guis "source=/tmp/.X11-unix,target=/tmp/.X11-unix,type=bind,consistency=cached", // gitconfig - "type=bind,source=/home/${localEnv:USER}/.gitconfig,target=/root/.gitconfig,readonly" + "type=bind,source=/home/${localEnv:USER}/.gitconfig,target=/home/rov/.gitconfig,readonly" ], - "workspaceFolder": "/root/rov-24", + "workspaceFolder": "/home/rov/rov-24", "customizations": { "vscode" : { "extensions": ["ms-python.flake8", "ms-azuretools.vscode-docker", diff --git a/.devcontainer/linux_test_environment/devcontainer.json b/.devcontainer/linux_test_environment/devcontainer.json new file mode 100644 index 00000000..6ccadb93 --- /dev/null +++ b/.devcontainer/linux_test_environment/devcontainer.json @@ -0,0 +1,24 @@ +{ + "name": "ROV Linux Test", + "build": { + "dockerfile": "../../Dockerfile" + }, + "mounts": [ + "type=bind,source=/home/${localEnv:USER}/.ssh,target=/home/rov/.ssh,readonly", + "source=/tmp/.X11-unix,target=/tmp/.X11-unix,type=bind,consistency=cached", + "type=bind,source=/home/${localEnv:USER}/.gitconfig,target=/home/rov/.gitconfig,readonly" + ], + "workspaceFolder": "/home/rov/rov-24", + "customizations": { + "vscode": { + "extensions": [ + "ms-python.flake8", + "ms-azuretools.vscode-docker", + "streetsidesoftware.code-spell-checker", + "ms-python.python", + "ms-python.mypy-type-checker" + ] + } + }, + "privileged": true +} \ No newline at end of file diff --git a/.devcontainer/macos/devcontainer.json b/.devcontainer/macos/devcontainer.json index 105bf055..d6303381 100644 --- a/.devcontainer/macos/devcontainer.json +++ b/.devcontainer/macos/devcontainer.json @@ -5,9 +5,9 @@ "DISPLAY": "unix:0" }, "mounts": [ - "type=bind,source=/Users/${localEnv:USER}/.ssh,target=/root/.ssh,readonly", + "type=bind,source=/Users/${localEnv:USER}/.ssh,target=/home/rov/.ssh,readonly", ], - "workspaceFolder": "/root/rov-24", + "workspaceFolder": "/home/rov/rov-24", "customizations": { "vscode" : { "extensions": ["ms-python.flake8", "ms-azuretools.vscode-docker", diff --git a/.devcontainer/windows/devcontainer.json b/.devcontainer/windows/devcontainer.json index 5d22c581..b60e5a76 100644 --- a/.devcontainer/windows/devcontainer.json +++ b/.devcontainer/windows/devcontainer.json @@ -4,7 +4,7 @@ "containerEnv": { "DISPLAY": "${localEnv:DISPLAY}" }, - "workspaceFolder": "/root/rov-24", + "workspaceFolder": "/home/rov/rov-24", "customizations": { "vscode" : { "extensions": ["ms-python.flake8", "ms-azuretools.vscode-docker", diff --git a/.dockerignore b/.dockerignore index e8b072e4..39eae289 100644 --- a/.dockerignore +++ b/.dockerignore @@ -1,3 +1,4 @@ build install -log \ No newline at end of file +log +*.egg-info \ No newline at end of file diff --git a/Dockerfile b/Dockerfile index 0eb0befe..e0e0461b 100644 --- a/Dockerfile +++ b/Dockerfile @@ -1,48 +1,99 @@ -FROM osrf/ros:iron-desktop-full +# syntax=docker/dockerfile-upstream:master-labs +# Done so --parents flag works -RUN sudo apt-get update -y +FROM osrf/ros:iron-desktop-full -# Install missing libxcb-cursor0 xvfb for PyQt unit testing +RUN apt-get update -y \ + && apt-get install --no-install-recommends -y \ + # Install Video for Linux + v4l-utils=1.22.1-2build1 -y \ + # Install lsusb + usbutils=1:014-1build1 \ + # Install nano + nano=6.2-1 \ + # Install pip + python3-pip=22.0.2+dfsg-1ubuntu0.4 \ + # Install geographiclib dependencies for mavros. + geographiclib-tools=1.52-1 \ + # Install missing libxcb-cursor0 xvfb for PyQt unit testing # https://pytest-qt.readthedocs.io/en/latest/troubleshooting.html -RUN sudo apt-get install xvfb -y + xvfb=2:21.1.4-2ubuntu1.7~22.04.8 \ + && apt-get upgrade -y \ + # Clean for better performance + && apt-get clean \ + && rm -rf /var/lib/apt/lists/* -# Install pip -RUN sudo apt-get install python3-pip -y +# Done here because file needs sudo perms +# Switch to bash so the process subsition works. aka <() +# Runs MAVROS helper install script +SHELL ["/bin/bash", "-c"] +RUN . <(wget -qO- https://raw.githubusercontent.com/mavlink/mavros/ros2/mavros/scripts/install_geographiclib_datasets.sh) -# Install Video for Linux -RUN sudo apt-get install v4l-utils -y +#Set up rov user +ARG USER_NAME=rov +ARG USER_UID=1000 +ARG USER_GID=1000 -# Install lsusb -RUN sudo apt-get install usbutils -y +RUN groupadd ${USER_NAME} --gid ${USER_GID} \ + && useradd -l -m ${USER_NAME} -u ${USER_UID} -g ${USER_GID} -s /bin/bash -# Install nano -RUN sudo apt-get install nano -y +# Gives Sudo perms to USER +RUN echo "${USER_NAME} ALL=(ALL) NOPASSWD:ALL" > /etc/sudoers.d/${USER_NAME} \ + && chmod 0440 /etc/sudoers.d/${USER_NAME} -RUN sudo apt-get update -y -RUN sudo apt-get upgrade -y +# Adds $USER to environment +ENV USER ${USER_NAME} +# Switches to rov user +USER ${USER_NAME} -WORKDIR /root/rov-24 +# Update Pip +RUN pip install --no-cache-dir --upgrade pip==24.0 +WORKDIR /home/${USER_NAME}/rov-24 + +# One might wonder why the following is done. +# It is done so that the dependencies can be cached without needing to be reinstalled +# each and everytime. Since these do not change too often this improves performance in most cases. +# Copies in Python deps COPY pyproject.toml . +# Copies in ROS deps +# https://docs.docker.com/engine/reference/builder/#copy---parents +COPY --parents --chown=${USER_NAME}:${USER_NAME} ./*/*/package.xml ./*/*/*/package.xml ./*/*/*/*/package.xml ./ +# Copies in Install Script +COPY .vscode/install_dependencies.sh . -RUN pip install --no-cache-dir . \ - && rm pyproject.toml +# Installs ROS and python dependencies +RUN ./install_dependencies.sh \ + # Clean up + && rm install_dependencies.sh -COPY . . +# Remove build warnings +ENV PYTHONWARNINGS ignore:::setuptools.command.install,ignore:::setuptools.command.easy_install,ignore:::pkg_resources # TODO for future nerd to do this via ENTRYPOINT which be better but, I could not get ENTRYPOINT to play with VsCODE. -RUN . /root/rov-24/.vscode/rov_setup.sh -RUN echo "$export PYTHONWARNINGS=ignore:::setuptools.command.install,ignore:::setuptools.command.easy_install,ignore:::pkg_resources" >> ~/.bashrc ; - -# Installs ROS and python dependencies -RUN . /root/rov-24/.vscode/install_dependencies.sh - -RUN . /opt/ros/iron/setup.sh \ - && PYTHONWARNINGS=ignore:::setuptools.command.install,ignore:::setuptools.command.easy_install,ignore:::pkg_resources; export PYTHONWARNINGS\ - && colcon build --symlink-install +COPY .vscode/rov_setup.sh . +RUN ./rov_setup.sh \ + && rm rov_setup.sh +COPY --chown=${USER_NAME}:${USER_NAME} .git .git # Remove identity file generated by action/checkout # Start by finding all files ending in config # Then removes file paths without "git" # Then removes the 'sshCommand' line from each file -RUN find . -name "*config" | grep git | while read -r line; do sed -i '/sshCommand/d' $line; done +SHELL ["/bin/bash", "-o", "pipefail", "-c"] +RUN find . -name "*config" | grep git | while read -r line; do sed -i "/sshCommand/d" "$line"; done + +# Do full copy and build as last step +COPY --chown=${USER_NAME}:${USER_NAME} . . + +ARG EXPECTED_OUTPUT="All system dependencies have been satisfied" + +# Checks that all rosdeps are installed. +RUN if [[ $(rosdep check -r --from-paths src --ignore-src) != "${EXPECTED_OUTPUT}" ]]; \ + then echo "ROS deps not all installed. Try adding another /* directory layer to the COPY instruction labeled 'Copies in ROS deps'."; \ + rosdep check -r --from-paths src --ignore-src; \ + exit 1; \ + fi + +RUN . /opt/ros/iron/setup.sh \ + && colcon build --symlink-install