Skip to content
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
7 changes: 7 additions & 0 deletions Makefile
Original file line number Diff line number Diff line change
Expand Up @@ -262,6 +262,13 @@ sim-drive-stop: ## Stop the rover
@$(CONTAINER_ENGINE) exec $(SIM_CONTAINER) bash -c \
'ign topic -t $(GZ_DRIVE_TOPIC) -m ignition.msgs.Twist -p "linear: {x: 0}, angular: {z: 0}"'

# Demo helpers
.PHONY: demo-swap
demo-swap: ## Fire an OTA rollout: circle → figure-eight (robot-app on sim-robot-01)
curl -sX POST http://localhost:8081/v1/ota/rollouts \
-H "content-type: application/json" \
-d '{"image_ref":"localhost:14050/robot-app:figure-eight-v1","smoke_command":"true","cohort_selector":{"robot_ids":["sim-robot-01"]}}'

# =============================================================================
# CI cluster (smoke / pre-push parity) — alternate ports so it can run
# alongside `make lab-up` on the same host. Used by .git-hooks/installer-smoke.sh
Expand Down
56 changes: 49 additions & 7 deletions installer/docker-compose/docker-compose.sim.yml
Original file line number Diff line number Diff line change
Expand Up @@ -53,6 +53,11 @@ services:
# this, OTA runs the container on the default bridge network and
# the new behaviour never reaches the simulated robot.
OTA_RUN_ARGS: "--network=temporal-hack-lab_default,-e,ROS_DOMAIN_ID=42,-e,RMW_IMPLEMENTATION=rmw_cyclonedds_cpp"
# Controller images are built --platform=linux/amd64 (they layer on
# ROS Humble's amd64-only base). On Apple Silicon, docker pull defaults
# to arm64 and refuses the amd64-only manifest. Force amd64 for both
# the pull and the run so OTA can swap controllers cleanly.
DOCKER_DEFAULT_PLATFORM: linux/amd64
# The repo is bind-mounted read-only. Go's workspace mode tries
# to update go.work.sum on `go run` and fails; turn the workspace
# off so the agent module's own go.mod/go.sum are authoritative.
Expand All @@ -71,13 +76,50 @@ services:
# perform OTA. CONTAINER_SOCK is supplied by the Makefile at
# compose time (resolves to docker.sock or podman.sock).
- ${CONTAINER_SOCK:-/var/run/docker.sock}:/var/run/docker.sock
# apt is needed to install the C toolchain for go-sqlite3 (cgo).
command: >
bash -c "
apt-get update -qq && apt-get install -y -qq build-essential >/dev/null &&
cd /src/agent &&
CGO_ENABLED=1 go run ./cmd/agent
"
# apt installs: build-essential for go-sqlite3 (cgo), docker-ce-cli for
# OTA's `docker run`. The Bookworm-default `docker.io` package's CLI is
# API 1.41 — too old for Docker Desktop's daemon (needs 1.44+).
# Block scalar style is `|` (literal, line-preserving) instead of `>`
# (folded). Folded scalar plus yamlfmt will helpfully wrap the long
# `echo "..." > docker.list` line and break the redirect — bash then
# sees the redirect as a standalone command and truncates docker.list
# to empty. Literal scalar keeps each `&&` clause on its own line and
# yamlfmt leaves it alone.
command: |
bash -c '
set -e
apt-get update -qq
apt-get install -y -qq build-essential ca-certificates curl gnupg >/dev/null
install -m 0755 -d /etc/apt/keyrings
curl -fsSL https://download.docker.com/linux/debian/gpg | gpg --dearmor -o /etc/apt/keyrings/docker.gpg
chmod a+r /etc/apt/keyrings/docker.gpg
ARCH=$$(dpkg --print-architecture)
echo "deb [arch=$$ARCH signed-by=/etc/apt/keyrings/docker.gpg] https://download.docker.com/linux/debian bookworm stable" > /etc/apt/sources.list.d/docker.list
apt-get update -qq
apt-get install -y -qq docker-ce-cli >/dev/null
cd /src/agent
exec env CGO_ENABLED=1 go run ./cmd/agent
'

# Initial robot-app behaviour. Auto-starts on `make sim-up` so the rover
# starts driving in a circle with zero clicks. OTA replaces this container
# by name (see agent/internal/ota/docker.go: docker rm -f robot-app +
# docker rename robot-app-new robot-app) — `container_name: robot-app` is
# required for that swap to find the right container.
robot-app:
image: localhost:14050/robot-app:circle-v1
container_name: robot-app
depends_on:
sim:
condition: service_started
mqtt:
condition: service_healthy
environment:
ROS_DOMAIN_ID: 42
RMW_IMPLEMENTATION: rmw_cyclonedds_cpp
networks:
- default
restart: unless-stopped

volumes:
bridge-sock:
Expand Down