Skip to content
Open
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
97 changes: 97 additions & 0 deletions .github/workflows/docker-build.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,97 @@
name: Docker Build

on:
workflow_dispatch:
inputs:
tag_latest:
description: 'Tag as latest'
required: true
type: choice
options:
- 'true'
- 'false'
default: 'false'
push:
# temp disable branch filter for testing
#branches: [main]
paths:
- 'docker/**'
- 'scripts/setup_*.sh'
- 'src/holosoma_inference/docker/Dockerfile'
- 'src/holosoma_retargeting/docker/Dockerfile'

permissions:
contents: read

env:
ECR_REPO: 982423663241.dkr.ecr.us-west-2.amazonaws.com

jobs:
build:
strategy:
fail-fast: false # continue on one build failing
matrix:
include:
# CPU-buildable images
- environment: inference
dockerfile: 'src/holosoma_inference/docker/Dockerfile'
runner_prefix: 'codebuild-holosoma-cpu-build'
- environment: retargeting
dockerfile: 'src/holosoma_retargeting/docker/Dockerfile'
runner_prefix: 'codebuild-holosoma-cpu-build'
# GPU-required images (setup scripts build/link against CUDA/IsaacSim)
- environment: holosoma
dockerfile: 'docker/Dockerfile'
runner_prefix: 'codebuild-holosoma-a10g-x1-gpu-build'
- environment: isaacgym
dockerfile: 'docker/isaacgym.Dockerfile'
runner_prefix: 'codebuild-holosoma-a10g-x1-gpu-build'
- environment: isaacsim
dockerfile: 'docker/isaacsim.Dockerfile'
runner_prefix: 'codebuild-holosoma-a10g-x1-gpu-build'
- environment: mujoco
dockerfile: 'docker/mujoco.Dockerfile'
runner_prefix: 'codebuild-holosoma-a10g-x1-gpu-build'
#TODO: add mujoco warp
name: Build ${{ matrix.environment }} Docker Image
continue-on-error: true
runs-on: ${{ matrix.runner_prefix }}-${{ github.run_id }}-${{ github.run_attempt }}
steps:
- name: Checkout code
uses: actions/checkout@v6

- name: Generate Image name and path
id: name
# image name should be `holosoma` or `holsoma-${environment}`
run: |
IMAGE_NAME="${{ matrix.environment == 'holosoma' && '' || 'holosoma-' }}${{ matrix.environment }}"
IMAGE_PATH="${{ env.ECR_REPO }}/${IMAGE_NAME}"
echo "image_path=${IMAGE_PATH}" >> "$GITHUB_OUTPUT"

# might be unnecessary
- name: Set up Docker Buildx
uses: docker/setup-buildx-action@v3

- name: Generate image tags
id: tags
run: |
tags="${{ steps.name.outputs.image_path }}:$(date -u +%Y_%m%d_%H%M)"
if [[ "${{ inputs.tag_latest || 'false' }}" == "true" ]]; then
tags="$tags,${{ steps.name.outputs.image_path }}:latest"
fi
echo "tags=$tags" >> "$GITHUB_OUTPUT"

- name: Build and push Docker image
uses: docker/build-push-action@v5
with:
context: .
file: "${{ matrix.dockerfile }}"
push: true
tags: "${{ steps.tags.outputs.tags }}"
cache-from: type=registry,ref=${{ steps.name.outputs.image_path }}:buildcache
cache-to: type=registry,ref=${{ steps.name.outputs.image_path }}:buildcache,mode=max

- name: Summary
run: |
echo "## Docker Build Summary" >> "$GITHUB_STEP_SUMMARY"
echo "- **Tags:** \`${{ steps.tags.outputs.tags }}\`" >> "$GITHUB_STEP_SUMMARY"
75 changes: 37 additions & 38 deletions docker/build_and_push.sh
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@
# Usage:
# bash docker/build_and_push.sh # build & push all images
# bash docker/build_and_push.sh mujoco retarget # only matching images
# bash docker/build_and_push.sh --no-push # build only, skip push
# bash docker/build_and_push.sh --latest # also tag and push as :latest
# bash docker/build_and_push.sh --dry-run # print commands, do nothing
#
# Environment variables:
Expand Down Expand Up @@ -34,13 +34,13 @@ IMAGES=(
)

# ── Parse flags ──────────────────────────────────────────────────────
NO_PUSH=false
TAG_LATEST=false
DRY_RUN=false
FILTERS=()

for arg in "$@"; do
case "$arg" in
--no-push) NO_PUSH=true ;;
--latest) TAG_LATEST=true ;;
--dry-run) DRY_RUN=true ;;
--help|-h)
sed -n '2,/^$/{ s/^# \?//; p }' "$0"
Expand Down Expand Up @@ -81,32 +81,30 @@ for cmd in docker; do
fi
done

if ! $NO_PUSH && ! $DRY_RUN; then
if ! $DRY_RUN; then
if ! command -v aws &>/dev/null; then
echo "Error: aws CLI is not installed (required for push)" >&2; exit 1
fi
fi

# ── ECR authentication ──────────────────────────────────────────────
if ! $NO_PUSH; then
echo "==> Configuring ECR credential helper for ${ECR_REPO}"
if ! $DRY_RUN; then
# Ensure docker config dir exists
mkdir -p ~/.docker

# Add ecr-login credential helper for our registry if not already present
if [ ! -f ~/.docker/config.json ]; then
echo '{}' > ~/.docker/config.json
fi
echo "==> Configuring ECR credential helper for ${ECR_REPO}"
if ! $DRY_RUN; then
# Ensure docker config dir exists
mkdir -p ~/.docker

# Add ecr-login credential helper for our registry if not already present
if [ ! -f ~/.docker/config.json ]; then
echo '{}' > ~/.docker/config.json
fi

if ! jq -e ".credHelpers[\"${ECR_REPO}\"]" ~/.docker/config.json &>/dev/null; then
tmp=$(mktemp)
jq --arg repo "$ECR_REPO" '.credHelpers[$repo] = "ecr-login"' ~/.docker/config.json > "$tmp" \
&& mv "$tmp" ~/.docker/config.json
echo " Added ecr-login credential helper for ${ECR_REPO}"
else
echo " ECR credential helper already configured"
fi
if ! jq -e ".credHelpers[\"${ECR_REPO}\"]" ~/.docker/config.json &>/dev/null; then
tmp=$(mktemp)
jq --arg repo "$ECR_REPO" '.credHelpers[$repo] = "ecr-login"' ~/.docker/config.json > "$tmp" \
&& mv "$tmp" ~/.docker/config.json
echo " Added ecr-login credential helper for ${ECR_REPO}"
else
echo " ECR credential helper already configured"
fi
fi

Expand All @@ -125,30 +123,31 @@ for entry in "${IMAGES[@]}"; do
echo ""
echo "==> Building ${image_name} from ${dockerfile}"

# tags: date tag + latest
tags=(-t "${full_image}:latest" -t "${full_image}:${TAG}")
# tags: always date tag, optionally latest
tags=(-t "${full_image}:${TAG}")
if $TAG_LATEST; then
tags+=(-t "${full_image}:latest")
fi

if run env DOCKER_BUILDKIT=1 docker build "${tags[@]}" -f "${dockerfile}" "${ROOT_REPO}"; then
echo " Built: ${image_name}"

if ! $NO_PUSH; then
echo " Pushing ${image_name}..."
push_ok=true
echo " Pushing ${image_name}..."
push_ok=true
if ! run docker push "${full_image}:${TAG}"; then
push_ok=false
fi
if $TAG_LATEST; then
if ! run docker push "${full_image}:latest"; then
push_ok=false
fi
if ! run docker push "${full_image}:${TAG}"; then
push_ok=false
fi
fi

if $push_ok; then
SUCCEEDED+=("$image_name")
else
echo " FAILED to push: ${image_name}" >&2
FAILED+=("$image_name")
fi
else
if $push_ok; then
SUCCEEDED+=("$image_name")
else
echo " FAILED to push: ${image_name}" >&2
FAILED+=("$image_name")
fi
else
echo " FAILED to build: ${image_name}" >&2
Expand Down Expand Up @@ -196,6 +195,6 @@ if [[ ${#SUCCEEDED[@]} -eq 0 ]] && [[ ${#FAILED[@]} -eq 0 ]]; then
exit 1
fi
echo " Tag: ${TAG}"
$NO_PUSH && echo " (push skipped — --no-push)"
$TAG_LATEST && echo " (also tagged as :latest)"
$DRY_RUN && echo " (dry run — nothing was executed)"
echo " Done."
4 changes: 2 additions & 2 deletions src/holosoma_inference/holosoma_inference/utils/network.py
Original file line number Diff line number Diff line change
@@ -1,13 +1,13 @@
"""Network interface auto-detection for robot communication."""

import os
from pathlib import Path

_SKIP_PREFIXES = ("lo", "wl", "docker", "br-", "veth", "virbr", "vnet", "tun", "tap")


def detect_robot_interface() -> str:
"""Return the name of the single wired NIC that is operationally UP."""
for ifname in sorted(os.listdir("/sys/class/net/")):
for ifname in sorted(Path("/sys/class/net/").iterdir()):
if any(ifname.startswith(p) for p in _SKIP_PREFIXES):
continue
try:
Expand Down
Loading