8585 local logs_pid=""
8686 local wait_pid=""
8787 local docker_wait_file="/tmp/.docker_exit_${container_name}"
88+ local docker_runtime_dir=""
8889
8990 # Kill the container immediately if the runner is cancelled.
9091 # The GitHub Actions runner can deliver HUP, INT, or TERM on cancellation
9495 docker kill '${container_name}' 2>/dev/null || true; \
9596 docker rm -f '${container_name}' 2>/dev/null || true; \
9697 rm -f '${docker_wait_file}'; \
98+ if [ -n \"\$docker_runtime_dir\" ]; then rm -rf \"\$docker_runtime_dir\" 2>/dev/null || true; fi; \
9799 if [ -n \"\$logs_pid\" ]; then kill \"\$logs_pid\" 2>/dev/null || true; fi; \
98100 if [ -n \"\$wait_pid\" ]; then kill \"\$wait_pid\" 2>/dev/null || true; fi; \
99101 exit 130" HUP INT TERM
@@ -180,16 +182,56 @@ runs:
180182 docker_env_vars="$docker_env_vars -e TEST_EXTRA_PIP_PACKAGES"
181183 fi
182184
183- echo "Docker environment variables: '$docker_env_vars'"
184-
185185 # Volume mount for deps-cache-hit mode: bind-mount the checked-out
186186 # source code over /workspace/isaaclab instead of baking it into the image.
187187 docker_volume_args=""
188+ docker_user_args=""
188189 if [ -n "$volume_mount_source" ]; then
189- docker_volume_args="-v ${volume_mount_source}:/workspace/isaaclab"
190+ host_uid="$(id -u)"
191+ host_gid="$(id -g)"
192+ host_user="$(id -un)"
193+ # Kit writes generated cache, config, data, and log files outside
194+ # the Isaac Lab source tree. Provide writable runtime storage for
195+ # host-uid test runs, mirroring the compose/singularity mounts.
196+ docker_runtime_dir="$(mktemp -d "${RUNNER_TEMP:-/tmp}/isaaclab-docker-runtime.XXXXXX")"
197+ mkdir -p \
198+ "${docker_runtime_dir}/home/.cache" \
199+ "${docker_runtime_dir}/home/.local/share/ov/data" \
200+ "${docker_runtime_dir}/home/.local/share/ov/pkg" \
201+ "${docker_runtime_dir}/home/.nv/ComputeCache" \
202+ "${docker_runtime_dir}/home/.nvidia-omniverse/config" \
203+ "${docker_runtime_dir}/home/.nvidia-omniverse/logs" \
204+ "${docker_runtime_dir}/home/Documents/Kit/shared" \
205+ "${docker_runtime_dir}/isaac-sim/kit/cache" \
206+ "${docker_runtime_dir}/isaac-sim/kit/data" \
207+ "${docker_runtime_dir}/isaac-sim/kit/logs" \
208+ "${docker_runtime_dir}/isaac-sim/cache" \
209+ "${docker_runtime_dir}/isaac-sim/computecache" \
210+ "${docker_runtime_dir}/isaac-sim/config" \
211+ "${docker_runtime_dir}/isaac-sim/data" \
212+ "${docker_runtime_dir}/isaac-sim/logs" \
213+ "${docker_runtime_dir}/isaac-sim/pkg"
214+ docker_volume_args="\
215+ -v ${volume_mount_source}:/workspace/isaaclab:rw \
216+ -v ${docker_runtime_dir}/home:/tmp/isaaclab-ci-home:rw \
217+ -v ${docker_runtime_dir}/isaac-sim/kit/cache:/isaac-sim/kit/cache:rw \
218+ -v ${docker_runtime_dir}/isaac-sim/kit/data:/isaac-sim/kit/data:rw \
219+ -v ${docker_runtime_dir}/isaac-sim/kit/logs:/isaac-sim/kit/logs:rw \
220+ -v ${docker_runtime_dir}/isaac-sim/cache:/isaac-sim/.cache:rw \
221+ -v ${docker_runtime_dir}/isaac-sim/computecache:/isaac-sim/.nv/ComputeCache:rw \
222+ -v ${docker_runtime_dir}/isaac-sim/config:/isaac-sim/.nvidia-omniverse/config:rw \
223+ -v ${docker_runtime_dir}/isaac-sim/data:/isaac-sim/.local/share/ov/data:rw \
224+ -v ${docker_runtime_dir}/isaac-sim/logs:/isaac-sim/.nvidia-omniverse/logs:rw \
225+ -v ${docker_runtime_dir}/isaac-sim/pkg:/isaac-sim/.local/share/ov/pkg:rw"
226+ docker_user_args="--user ${host_uid}:${host_gid}"
227+ docker_env_vars="$docker_env_vars -e HOME=/tmp/isaaclab-ci-home -e XDG_CACHE_HOME=/tmp/isaaclab-ci-home/.cache -e XDG_DATA_HOME=/tmp/isaaclab-ci-home/.local/share -e USER=${host_user} -e LOGNAME=${host_user}"
190228 echo "🔵 Volume-mounting ${volume_mount_source} >> /workspace/isaaclab"
229+ echo "🔵 Mounting writable Docker runtime storage from ${docker_runtime_dir}"
230+ echo "🔵 Running volume-mounted container as host uid:gid ${host_uid}:${host_gid} (${host_user})"
191231 fi
192232
233+ echo "Docker environment variables: '$docker_env_vars'"
234+
193235 # Run tests in a detached container and follow logs. Running detached
194236 # means the container lifecycle is independent of the shell - if the
195237 # runner kills this step on cancellation, the `if: always()` cleanup
@@ -206,6 +248,7 @@ runs:
206248 --ulimit nofile=65536:65536 \
207249 --ulimit nproc=4096:4096 \
208250 $docker_volume_args \
251+ $docker_user_args \
209252 $docker_env_vars \
210253 $image_tag \
211254 -c "
@@ -318,6 +361,9 @@ runs:
318361 # Clean up container
319362 echo "🔵 Cleaning up Docker container..."
320363 docker rm $container_name 2>/dev/null || echo "🟠 Container cleanup failed, but continuing..."
364+ if [ -n "$docker_runtime_dir" ]; then
365+ rm -rf "$docker_runtime_dir" || echo "🟠 Docker runtime storage cleanup failed, but continuing..."
366+ fi
321367
322368 return $DOCKER_EXIT
323369 }
0 commit comments