diff --git a/.github/workflows/build.yaml b/.github/workflows/build.yaml index f9ee6b2..2ae7b67 100644 --- a/.github/workflows/build.yaml +++ b/.github/workflows/build.yaml @@ -3,10 +3,10 @@ name: Build on: push: branches: - - main + - humble-docker pull_request: branches: - - main + - humble-docker jobs: build: @@ -16,5 +16,4 @@ jobs: - name: Build run: | nix build -Lv .#OSLiteImage - nix build -Lv .#OSFullImage nix fmt -- -c . diff --git a/OS-image/default.nix b/OS-image/default.nix index dcf0ea9..e2037cb 100644 --- a/OS-image/default.nix +++ b/OS-image/default.nix @@ -1,6 +1,7 @@ -{ OSName, OSVersion, buildSystem, lib, pkgs, fetchurl, stdenv, vmTools, ... }: +{ OSName, OSVersion, buildSystem, lib, pkgs, fetchurl, stdenv, vmTools +, dockerTools, ... }: let - imageSize = 8192; + imageSize = 12000; memSize = 4096; tools = import ./tools.nix { inherit lib pkgs; }; @@ -9,7 +10,17 @@ let files-full = pkgs.callPackage ./files-full { }; - scripts = pkgs.callPackage ./scripts { inherit files-lite files-full; }; + leoHumbleContainer = dockerTools.pullImage { + imageName = "ghcr.io/leorover/leo_humble_docker"; + imageDigest = + "sha256:eb9ab4c9d03d332c097d1114fbbe0d1d1a3579300c12de87c409cb1154c057c6"; # v3 + sha256 = "sha256-Yst+BX7Iw6ngtJJOdTZJwlUYviBGZ3qu0TtFFdMAKkk="; + arch = "arm64"; + }; + + scripts = pkgs.callPackage ./scripts { + inherit files-lite files-full leoHumbleContainer; + }; packageLists = let noble-updates-stamp = "20260309T120000Z"; @@ -156,6 +167,7 @@ let "rpi-eeprom" # Raspberry Pi EEPROM utilities ## Networking stuff + "ca-certificates" # CA certificates for HTTPS "netplan.io" # network configuration utility "iproute2" # ip cli utilities "iputils-ping" # ping utility @@ -174,28 +186,18 @@ let "hostname" # hostname management "rtw88-dkms" # Realtek WiFi driver - "---" + ## Containers + "podman" # container management + "uidmap" # user namespace support for podman - # STAGE 2 - ROS base packages + "---" + # STAGE 2 - ommitted # Added here to fix a problem with deb closure generator which cannot properly # resolve dependencies like "python3-distro (>= 1.4.0) | python3 (<< 3.8)" "python3-distro" "ros2-apt-source" # Configures sources for ROS 2 repo - # "ros-dev-tools" # ROS development tools (rosdep, colcon, vcs etc.) - # The newest ROS snapshot is missing ros-dev-tools, so we install its dependencies instead - "build-essential" - "cmake" - "python3-setuptools" - "python3-bloom" - "python3-colcon-common-extensions" - "python3-colcon-mixin" - "python3-rosdep" - "python3-vcstool" - "wget" - - "ros-jazzy-ros-base" # ROS base packages "---" @@ -203,11 +205,6 @@ let "python3-rpi-lgpio" # Replacement for RPi.GPIO which supports RPi 5 "python3-stm32loader" # Tool for flashing LeoCore "leo-ui" # Web UI for controlling Leo Rover - "ros-jazzy-leo-robot" # Leo Rover ROS packages - "ros-jazzy-leo-camera" # hidden dependency of leo_robot - "ros-jazzy-compressed-image-transport" # image transport plugin that provides compressed image streams - "ros-jazzy-micro-ros-agent" # For talking with LeoCore - "ros-jazzy-aruco-opencv" # For aruco tracking "---" @@ -230,8 +227,6 @@ let "breeze-cursor-theme" # LXQt cursor theme "firefox-esr" # Web browser "tigervnc-scraping-server" # VNC server - "ros-jazzy-desktop" # ROS desktop packages - "ros-jazzy-leo-desktop" # Leo-specific ROS desktop packages ]; }) { inherit fetchurl; }; diff --git a/OS-image/files-lite/default.nix b/OS-image/files-lite/default.nix index d13c100..c357dd0 100644 --- a/OS-image/files-lite/default.nix +++ b/OS-image/files-lite/default.nix @@ -3,7 +3,7 @@ { stdenv, fetchurl }: let fictionlab-archive-keyring = (fetchurl { - url = "https://files.fictionlab.pl/repo/fictionlab.gpg"; + url = "https://archive.fictionlab.pl/fictionlab.gpg"; sha256 = "sha256-noqi5NcMDrnwMp9JFVUrLJkH65WH9/EDISQIVT8Hnf8="; }); diff --git a/OS-image/files-lite/etc/profile.d/99-ros-container-status.sh b/OS-image/files-lite/etc/profile.d/99-ros-container-status.sh new file mode 100644 index 0000000..7a3fab2 --- /dev/null +++ b/OS-image/files-lite/etc/profile.d/99-ros-container-status.sh @@ -0,0 +1,10 @@ +#!/bin/bash + +# Ensure this only prints for interactive logins +if [[ $- == *i* ]]; then + if systemctl --user is-active --quiet ros-nodes 2>/dev/null && systemctl --user is-active --quiet uros-agent 2>/dev/null; then + printf "ROS Humble containers are running. To enter the ROS bash shell, run: ros-container-bash\n" + else + printf "One or more ROS Humble containers are not running - you can find more info with: ros-status\n" + fi +fi \ No newline at end of file diff --git a/OS-image/files-lite/etc/ros/aliases b/OS-image/files-lite/etc/ros/aliases index f4b9d20..4eef305 100644 --- a/OS-image/files-lite/etc/ros/aliases +++ b/OS-image/files-lite/etc/ros/aliases @@ -1,3 +1,4 @@ +alias ros-container-bash="podman exec -ti ros-nodes /bin/bash -ic 'source install/setup.bash; exec /bin/bash -i'" alias ros-nodes-logs="journalctl -b --no-pager --no-hostname -all -n 1000 --user-unit ros-nodes" alias ros-nodes-start="systemctl --user start ros-nodes" alias ros-nodes-restart="systemctl --user restart ros-nodes" diff --git a/OS-image/files-lite/etc/ros/setup.bash b/OS-image/files-lite/etc/ros/setup.bash index 7aba803..d6bf51b 100644 --- a/OS-image/files-lite/etc/ros/setup.bash +++ b/OS-image/files-lite/etc/ros/setup.bash @@ -1,6 +1,3 @@ -# Source the ROS workspace -source /opt/ros/jazzy/setup.bash - # Source aliases for systemd user services source /etc/ros/aliases diff --git a/OS-image/files-lite/etc/systemd/user/ros-nodes.service b/OS-image/files-lite/etc/systemd/user/ros-nodes.service index 1422f4c..3c17b7f 100644 --- a/OS-image/files-lite/etc/systemd/user/ros-nodes.service +++ b/OS-image/files-lite/etc/systemd/user/ros-nodes.service @@ -3,12 +3,26 @@ Description=ROS nodes PartOf=ros.target [Service] -Type=simple +Type=exec ExecStartPre=/usr/lib/systemd/systemd-networkd-wait-online -ExecStart=/usr/lib/ros/ros-nodes -KillSignal=SIGINT -KillMode=process -TimeoutStopSec=30 +ExecStartPre=-/usr/bin/podman rm -f ros-nodes +ExecStartPre=-/bin/rm -f /%t/ros-nodes.cid +ExecStart=/usr/bin/podman run --rm \ + --privileged \ + --net=host \ + --ipc=host \ + --pid=host \ + --security-opt label=disable \ + --name ros-nodes \ + -v /dev:/dev \ + -v /usr/lib/ros:/usr/lib/ros \ + -v /etc/ros:/etc/ros \ + -v /home/%u/.ros:/root/.ros \ + --group-add keep-groups \ + --cidfile=/%t/ros-nodes.cid \ + ghcr.io/leorover/leo_humble_docker ros-nodes +KillSignal=none +ExecStop=/usr/bin/podman stop --cidfile=/%t/ros-nodes.cid [Install] WantedBy=ros.target diff --git a/OS-image/files-lite/etc/systemd/user/uros-agent.service b/OS-image/files-lite/etc/systemd/user/uros-agent.service index a6d825a..aa3b911 100644 --- a/OS-image/files-lite/etc/systemd/user/uros-agent.service +++ b/OS-image/files-lite/etc/systemd/user/uros-agent.service @@ -3,9 +3,25 @@ Description=Micro-ROS agent PartOf=ros.target [Service] -Type=simple +Type=exec ExecStartPre=/usr/lib/systemd/systemd-networkd-wait-online -ExecStart=/usr/lib/ros/uros-agent +ExecStartPre=-/usr/bin/podman rm -f uros-agent +ExecStartPre=-/bin/rm -f /%t/uros-agent.cid +ExecStart=/usr/bin/podman run --rm \ + --privileged \ + --net=host \ + --ipc=host \ + --pid=host \ + --security-opt label=disable \ + --name uros-agent \ + -v /dev:/dev \ + -v /usr/lib/ros:/usr/lib/ros:ro \ + -v /etc/ros:/etc/ros:ro \ + --group-add keep-groups \ + --cidfile=/%t/uros-agent.cid \ + ghcr.io/leorover/leo_humble_docker uros-agent +KillSignal=none +ExecStop=/usr/bin/podman stop --cidfile=/%t/uros-agent.cid Restart=on-failure RestartSec=5 diff --git a/OS-image/scripts/buildStage4.sh b/OS-image/scripts/buildStage4.sh index 74adfcd..336a916 100755 --- a/OS-image/scripts/buildStage4.sh +++ b/OS-image/scripts/buildStage4.sh @@ -72,7 +72,6 @@ done # Change file ownership chown ${USER_NAME}:${USER_NAME} -R "/etc/ros" -chown root:root -R "/etc/ros/rosdep" # Enable user services su - ${USER_NAME} -c "systemctl --user enable ros-nodes" @@ -80,6 +79,33 @@ su - ${USER_NAME} -c "systemctl --user enable uros-agent" su - ${USER_NAME} -c "systemctl --user enable ros.target" CHROOT +# Install the container image archive +mkdir -p /mnt/tmp +cp -v "${LEO_HUMBLE_CONTAINER}" /mnt/tmp/leo_humble_container.tar + +# Load the Podman container image +my_chroot /mnt podman load -i /tmp/leo_humble_container.tar + +# Remove the Podman container image archive +rm -vf /mnt/tmp/leo_humble_container.tar + +# Move the Podman container storage to the user's home directory +mkdir -vp "/mnt/home/${USER_NAME}/.local/share/containers" +mv -v /mnt/var/lib/containers/storage "/mnt/home/${USER_NAME}/.local/share/containers/storage" + +# Remove the old Podman container storage database so it will be recreated +rm /mnt/home/${USER_NAME}/.local/share/containers/storage/db.sql + +# Fix ownership of the Podman container storage +my_chroot /mnt chown -R ${USER_NAME}:${USER_NAME} "/home/${USER_NAME}/.local" + +# Clear root podman cache +rm -rf /mnt/var/lib/containers + +# Create needed directories in the user's home directory +mkdir -vp "/mnt/home/${USER_NAME}/.ros" +my_chroot /mnt chown ${USER_NAME}:${USER_NAME} "/home/${USER_NAME}/.ros" + # Enable lingering for default user mkdir -p -m 755 "/mnt/var/lib/systemd/linger" touch "/mnt/var/lib/systemd/linger/${USER_NAME}" diff --git a/OS-image/scripts/default.nix b/OS-image/scripts/default.nix index 9da46d5..9ad1e59 100644 --- a/OS-image/scripts/default.nix +++ b/OS-image/scripts/default.nix @@ -1,4 +1,4 @@ -{ files-lite, files-full, pkgs, stdenv, makeWrapper }: { +{ files-lite, files-full, leoHumbleContainer, pkgs, stdenv, makeWrapper }: { stage1 = stdenv.mkDerivation { name = "scripts-stage1"; src = ./buildStage1.sh; @@ -75,7 +75,8 @@ lib.makeBinPath [ coreutils gnused systemd util-linux ] }" \ --set FILES_DIR ${files-lite} \ - --set UDEVD "${pkgs.systemd}/lib/systemd/systemd-udevd" + --set UDEVD "${pkgs.systemd}/lib/systemd/systemd-udevd" \ + --set LEO_HUMBLE_CONTAINER ${leoHumbleContainer} ''; }; diff --git a/flake.nix b/flake.nix index 13a397c..08527b3 100644 --- a/flake.nix +++ b/flake.nix @@ -13,7 +13,7 @@ pkgs = (import nixpkgs) { inherit system; }; OSName = "LeoOS"; - OSVersion = "2.4.0"; + OSVersion = "2.4.0-humble-1"; OSImageDerivations = pkgs.callPackage ./OS-image { inherit OSName OSVersion;