[Unit] Description=Sanad fleet agent (EngineAI PM01) — telemetry + map + logs + alerts Documentation=file:/opt/sanad_api_eng/README.md After=network-online.target docker.service Wants=network-online.target [Service] Type=simple # Runs as root, deliberately: # * survives reboot with no `loginctl enable-linger` (the X2 deployment's one # open item — a user unit there does NOT come back after a power cycle) # * can read /var/lib/docker/containers/*/\*-json.log, which is how the Sanad # app's logs reach the fleet server. A non-root user gets EACCES there and # project_logs stays null forever. User=root WorkingDirectory=/opt/sanad_api_eng # set +u is REQUIRED: ROS's setup.bash reads unbound variables and would abort # the unit under set -u. ros_env.sh is the robot's OWN environment file — it # pins ROS_DOMAIN_ID=69, RMW_IMPLEMENTATION=rmw_cyclonedds_cpp and # CYCLONEDDS_URI (eth1). Sourcing it rather than restating those values means # the agent follows the robot if EngineAI ever changes them. ExecStart=/bin/bash -c 'set +u; \ . /opt/ros/humble/setup.bash >/dev/null 2>&1 || true; \ . /app/applications/install/bringup/ros_env.sh >/dev/null 2>&1 || true; \ exec /usr/bin/python3 -u /opt/sanad_api_eng/sanad_api_eng.py' Restart=always RestartSec=5 KillSignal=SIGINT TimeoutStopSec=15 StandardOutput=journal StandardError=journal SyslogIdentifier=sanad-api-eng [Install] WantedBy=multi-user.target