Skip to content

Fix worker images, code-upload git dependency, and CI/Cloud Agent Docker bootstrap#5141

Merged
RishabhJain2018 merged 8 commits into
masterfrom
cursor/fix-worker-py39-image-resolution-d2c6
Jul 8, 2026
Merged

Fix worker images, code-upload git dependency, and CI/Cloud Agent Docker bootstrap#5141
RishabhJain2018 merged 8 commits into
masterfrom
cursor/fix-worker-py39-image-resolution-d2c6

Conversation

@RishabhJain2018

@RishabhJain2018 RishabhJain2018 commented Jul 8, 2026

Copy link
Copy Markdown
Member

Summary

Fixes worker image resolution for challenges migrated to Python 3.9, addresses CI build failures, and resolves CodeRabbit review feedback.

Worker image resolution

  • get_worker_image_for_challenge() now resolves EvalAI-managed ECR images from worker_python_version, preserving existing tags when appropriate.
  • refresh_task_definition_for_challenge() syncs worker_image_url when the stored URL is an EvalAI-managed image that differs from the resolved image.

Docker / CI fixes

  • Pin cython==0.29.36 in all worker Dockerfiles (Python 3.9 wheel compatibility).
  • Pin PyJWT for py3.7/py3.8 worker builds; add PyYaml==5.4.1 to worker_py3_9.txt.
  • Add runtime import check (boto3, botocore, django, requests, yaml) in py3.9 worker Dockerfiles.
  • Add git to code-upload-worker Dockerfiles.

Cloud Agent bootstrap

  • Moved install script to cloud-agent/install.sh.
  • Use mktemp for dockerd logs; abort if no compose package is found.
  • Noble/Ubuntu 24.04 compatibility (docker-compose-v2, skip iptables-legacy).

Tests

  • Image resolution and tag preservation for EvalAI-managed workers.
  • worker_image_url sync on task definition refresh (including no-op when already synced).

Ops note

After deploy, refresh stale task definitions:

python manage.py refresh_worker_task_definitions --commit-id=<git-sha>
Open in Web Open in Cursor 

Summary by CodeRabbit

  • New Features

    • Improved cloud-agent setup with a bootstrap script that installs and starts Docker automatically, including fallback handling for systems without standard service startup support.
    • Added clearer guidance for Docker setup on Ubuntu 24.04.
  • Bug Fixes

    • Worker images now resolve more consistently across Python versions and tags.
    • Challenge worker images are updated only when needed during task definition refreshes.
    • Added package/version pinning to improve build reliability across worker images.
  • Documentation

    • Expanded setup instructions for local and cloud-agent environments.

…tored ECR URL

Challenges with worker_python_version=3.9 but a stale EvalAI-managed
worker_image_url pointing at worker-py3.7 were still deployed on Python 3.7
images, causing runtime import failures such as missing boto3.

Resolve EvalAI-managed worker images from worker_python_version while
preserving the existing commit tag, sync worker_image_url during task
definition refresh, and add worker image import verification to py3.9
Dockerfiles.

Co-authored-by: Rishabh Jain <rishabhjain2018@gmail.com>
@coderabbitai

coderabbitai Bot commented Jul 8, 2026

Copy link
Copy Markdown

Review Change Stack

Note

Reviews paused

It looks like this branch is under active development. To avoid overwhelming you with review comments due to an influx of new commits, CodeRabbit has automatically paused this review. You can configure this behavior by changing the reviews.auto_review.auto_pause_after_reviewed_commits setting.

Use the following commands to manage reviews:

  • @coderabbitai resume to resume automatic reviews.
  • @coderabbitai review to trigger a single review.

Use the checkboxes below for quick actions:

  • ▶️ Resume reviews
  • 🔍 Trigger review

Walkthrough

This PR refactors EvalAI-managed worker image tag resolution and task-definition refresh logic with expanded test coverage, updates worker Dockerfiles with dependency pins and verification steps, adds git to code-upload-worker runtime images, and introduces a cloud-agent Docker bootstrap script with updated documentation.

Changes

Worker image tag resolution and refresh

Layer / File(s) Summary
Worker image tag helper and canonical URI derivation
apps/challenges/aws_utils.py
Adds get_evalai_worker_image_tag() to resolve tags from commit_id or existing image URL, and updates get_worker_image_for_challenge() to always return a canonical EvalAI ECR URI for managed images.
Task definition refresh updates worker_image_url
apps/challenges/aws_utils.py
refresh_task_definition_for_challenge() now saves task_def_arn via update_fields and conditionally updates worker_image_url only when the managed image tag changed.
Unit tests for tag rebuild and refresh sync
tests/unit/challenges/test_aws_utils.py
Adds/extends tests validating tag rebuilding with commit_id, tag preservation without it, and worker_image_url sync behavior with correct update_fields.

Worker build and bootstrap updates

Layer / File(s) Summary
Worker dependency pins and verification
docker/dev/worker_py3_7/Dockerfile, docker/dev/worker_py3_8/Dockerfile, docker/dev/worker_py3_9/Dockerfile, docker/prod/worker_py3_7/Dockerfile, docker/prod/worker_py3_8/Dockerfile, docker/prod/worker_py3_9/Dockerfile, requirements/worker_py3_9.txt
Pins PyJWT, cython, and numpy versions across worker builders, adds PyYaml==5.4.1, separates cleanup and adds runtime import verification for Python 3.9 images.
Code-upload-worker runtime packages
docker/dev/code-upload-worker/Dockerfile, docker/prod/code-upload-worker/Dockerfile
Adds git, curl, and ca-certificates to runtime apt-get install steps with updated comments explaining the need for git.
Docker bootstrap install command
.cursor/environment.json, AGENTS.md, cloud-agent/install.sh
Runs a new bootstrap script before compose build; the script detects the compose package, configures iptables-legacy and Docker daemon settings, starts the daemon with a fallback, and installs Docker if missing; documentation is updated accordingly.

Estimated code review effort: 3 (Moderate) | ~30 minutes

Sequence Diagram(s)

sequenceDiagram
  participant Caller
  participant refresh_task_definition_for_challenge
  participant get_worker_image_for_challenge
  participant Challenge

  Caller->>refresh_task_definition_for_challenge: trigger refresh
  refresh_task_definition_for_challenge->>get_worker_image_for_challenge: resolve WORKER_IMAGE
  get_worker_image_for_challenge-->>refresh_task_definition_for_challenge: resolved_worker_image
  refresh_task_definition_for_challenge->>Challenge: save(update_fields=[task_def_arn, worker_image_url?])
Loading
sequenceDiagram
  participant EnvironmentSetup
  participant InstallScript
  participant AptPackageManager
  participant DockerDaemon

  EnvironmentSetup->>InstallScript: bash cloud-agent/install.sh
  InstallScript->>AptPackageManager: detect/install compose package + docker.io
  InstallScript->>InstallScript: configure_iptables_legacy_if_available
  InstallScript->>InstallScript: configure_docker_daemon (daemon.json)
  InstallScript->>DockerDaemon: start_docker_daemon (systemctl or dockerd fallback)
  DockerDaemon-->>InstallScript: docker info (poll up to 30s)
  InstallScript-->>EnvironmentSetup: print docker/compose versions
Loading

Possibly related PRs

  • Cloud-CV/EvalAI#5095: Introduces the AGENTS.md Cloud VM/Docker setup documentation file that this PR further modifies.
  • Cloud-CV/EvalAI#5125: Wires deployment to run task-definition refresh with COMMIT_ID, directly relying on this PR's updated refresh_task_definition_for_challenge logic.
🚥 Pre-merge checks | ✅ 5
✅ Passed checks (5 passed)
Check name Status Explanation
Description Check ✅ Passed Check skipped - CodeRabbit’s high-level summary is enabled.
Title check ✅ Passed The title accurately summarizes the main changes: worker image fixes, a code-upload git dependency, and Docker bootstrap updates for CI/Cloud Agent.
Docstring Coverage ✅ Passed No functions found in the changed files to evaluate docstring coverage. Skipping docstring coverage check.
Linked Issues check ✅ Passed Check skipped because no linked issues were found for this pull request.
Out of Scope Changes check ✅ Passed Check skipped because no linked issues were found for this pull request.
✨ Finishing Touches
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Commit unit tests in branch cursor/fix-worker-py39-image-resolution-d2c6

Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share

Comment @coderabbitai help to get the list of available commands.

install_dependencies.sh uses kubectl apply -k with github.com URLs for
EFS/EBS CSI drivers, which requires git in the container PATH.

Co-authored-by: Rishabh Jain <rishabhjain2018@gmail.com>

@coderabbitai coderabbitai Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 1

🧹 Nitpick comments (2)
tests/unit/challenges/test_aws_utils.py (1)

5903-5965: 📐 Maintainability & Code Quality | 🔵 Trivial | ⚡ Quick win

LGTM! The test properly verifies worker_image_url synchronization and save(update_fields=...) call without mocking get_image_settings_for_challenge, providing good integration coverage.

Consider adding a test for the no-op case where a managed worker_image_url already matches the resolved image — that path should save with only update_fields=["task_def_arn"].

🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@tests/unit/challenges/test_aws_utils.py` around lines 5903 - 5965, Add a unit
test for the no-op branch in refresh_task_definition_for_challenge where the
existing managed worker_image_url already matches the resolved image settings,
so only task_def_arn should be updated. Reuse the existing test setup around
refresh_task_definition_for_challenge and assert that challenge.save is called
with update_fields=["task_def_arn"] and that worker_image_url is left unchanged.
apps/challenges/aws_utils.py (1)

1103-1111: 📐 Maintainability & Code Quality | 🔵 Trivial | 💤 Low value

Wrap the conditional to fit black’s 79-char limit.

Suggested reformatting
         update_fields = ["task_def_arn"]
         resolved_worker_image = image_settings["WORKER_IMAGE"]
-        if challenge.worker_image_url and is_evalai_managed_submission_worker_image(
-            challenge.worker_image_url
-        ):
+        if (
+            challenge.worker_image_url
+            and is_evalai_managed_submission_worker_image(
+                challenge.worker_image_url
+            )
+        ):
             if challenge.worker_image_url != resolved_worker_image:
                 challenge.worker_image_url = resolved_worker_image
                 update_fields.append("worker_image_url")
         challenge.save(update_fields=update_fields)
🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@apps/challenges/aws_utils.py` around lines 1103 - 1111, The conditional in
aws_utils around challenge.worker_image_url and
is_evalai_managed_submission_worker_image exceeds Black’s 79-character limit and
should be reformatted. Wrap the if statement across multiple lines in the same
block that updates update_fields and challenge.worker_image_url, keeping the
logic unchanged while making the expression fit the formatter’s line-length
rules.

Source: Coding guidelines

🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

Inline comments:
In `@docker/prod/worker_py3_9/Dockerfile`:
- Around line 75-83: The runtime import check in the worker Dockerfile uses
yaml, but the package is not declared in the worker dependency set. Add PyYAML
to the relevant requirements used by the prod worker build, specifically the
worker_py3_9 requirements chain that feeds submission_worker.py, and ensure the
dependency is included where the Dockerfile’s import verification expects it.

---

Nitpick comments:
In `@apps/challenges/aws_utils.py`:
- Around line 1103-1111: The conditional in aws_utils around
challenge.worker_image_url and is_evalai_managed_submission_worker_image exceeds
Black’s 79-character limit and should be reformatted. Wrap the if statement
across multiple lines in the same block that updates update_fields and
challenge.worker_image_url, keeping the logic unchanged while making the
expression fit the formatter’s line-length rules.

In `@tests/unit/challenges/test_aws_utils.py`:
- Around line 5903-5965: Add a unit test for the no-op branch in
refresh_task_definition_for_challenge where the existing managed
worker_image_url already matches the resolved image settings, so only
task_def_arn should be updated. Reuse the existing test setup around
refresh_task_definition_for_challenge and assert that challenge.save is called
with update_fields=["task_def_arn"] and that worker_image_url is left unchanged.
🪄 Autofix (Beta)

Fix all unresolved CodeRabbit comments on this PR:

  • Push a commit to this branch (recommended)
  • Create a new PR with the fixes

ℹ️ Review info
⚙️ Run configuration

Configuration used: Path: .coderabbit.yaml

Review profile: CHILL

Plan: Pro Plus

Run ID: a7bee042-5ae9-4cac-bb92-ac44f348e498

📥 Commits

Reviewing files that changed from the base of the PR and between 1c59607 and 4b74a3f.

📒 Files selected for processing (4)
  • apps/challenges/aws_utils.py
  • docker/dev/worker_py3_9/Dockerfile
  • docker/prod/worker_py3_9/Dockerfile
  • tests/unit/challenges/test_aws_utils.py

Comment thread docker/prod/worker_py3_9/Dockerfile
- Pin Cython to 0.29.36 so Python 3.8/3.9 worker images use prebuilt wheels
  instead of failing to compile cython==0.29 from source during CI setup
- Override PyJWT in worker py3.7/py3.8 Docker builds (2.13 requires Python 3.9+)
- Add Cloud Agent bootstrap script and invoke it from environment.json before
  docker compose build

Co-authored-by: Rishabh Jain <rishabhjain2018@gmail.com>
@RishabhJain2018
RishabhJain2018 marked this pull request as ready for review July 8, 2026 06:19
@cursor

cursor Bot commented Jul 8, 2026

Copy link
Copy Markdown

Bugbot is not enabled for your account, so this pull request was not reviewed.

Enable Bugbot in the Cursor dashboard to get automatic reviews on future PRs.

- Use docker-compose-v2 on Noble (docker-compose-plugin is unavailable)
- Skip iptables-legacy when alternatives are not present
- Fall back to starting dockerd directly when systemd is unavailable
- Use sudo for docker daemon health checks before group membership applies
- Apply black formatting fix to aws_utils.py for CI code quality

Co-authored-by: Rishabh Jain <rishabhjain2018@gmail.com>
@cursor cursor Bot changed the title Fix worker image resolution when worker_python_version differs from stored ECR URL Fix worker images, code-upload git dependency, and CI/Cloud Agent Docker bootstrap Jul 8, 2026

@coderabbitai coderabbitai Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 2

🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

Inline comments:
In `@scripts/cloud-agent/bootstrap-docker.sh`:
- Around line 73-85: The Docker bootstrap flow in bootstrap-docker.sh does not
verify the result of ensure_docker_compose_package before using compose_package,
so an unavailable compose package can lead to an empty apt-get install argument.
Update the installation path to check the return status of
ensure_docker_compose_package immediately after calling it, and abort with a
clear error message if no compose package is found. Keep the fix localized to
the Docker install block that calls ensure_docker_compose_package, apt-get
install, and configure_docker_daemon.
- Around line 56-58: The dockerd startup block writes logs to a predictable /tmp
path, which is vulnerable to symlink attacks. Update the bootstrap-docker.sh
logic around the dockerd launch to use a unique temporary file created with
mktemp instead of the hardcoded /tmp/dockerd.log, and direct dockerd output to
that generated path in the background command.
🪄 Autofix (Beta)

Fix all unresolved CodeRabbit comments on this PR:

  • Push a commit to this branch (recommended)
  • Create a new PR with the fixes

ℹ️ Review info
⚙️ Run configuration

Configuration used: Path: .coderabbit.yaml

Review profile: CHILL

Plan: Pro Plus

Run ID: b75435b9-c27c-4201-9a26-b767d963553f

📥 Commits

Reviewing files that changed from the base of the PR and between 9290a8f and 56c8d97.

📒 Files selected for processing (3)
  • AGENTS.md
  • apps/challenges/aws_utils.py
  • scripts/cloud-agent/bootstrap-docker.sh
🚧 Files skipped from review as they are similar to previous changes (1)
  • apps/challenges/aws_utils.py

Comment thread cloud-agent/install.sh Outdated
Comment thread cloud-agent/install.sh
cursoragent and others added 4 commits July 8, 2026 06:34
Relocate the Docker bootstrap script from scripts/cloud-agent/ to a
top-level cloud-agent/ folder and update environment.json and AGENTS.md.

Co-authored-by: Rishabh Jain <rishabhjain2018@gmail.com>
submission_worker imports yaml and the worker_py3_9 Dockerfile verifies it
at build time. Declare PyYaml explicitly in worker_py3_9.txt (matching the
code-upload worker pin) instead of relying only on the transitive common.txt
dependency.

Co-authored-by: Rishabh Jain <rishabhjain2018@gmail.com>
- Use mktemp for dockerd log path in cloud-agent/install.sh
- Abort Docker install when no compose package is available
- Add unit test for no-op worker_image_url sync on task def refresh

Co-authored-by: Rishabh Jain <rishabhjain2018@gmail.com>
Co-authored-by: Rishabh Jain <rishabhjain2018@gmail.com>
@codecov

codecov Bot commented Jul 8, 2026

Copy link
Copy Markdown

Codecov Report

✅ All modified and coverable lines are covered by tests.
✅ Project coverage is 91.21%. Comparing base (1c59607) to head (0bd75ac).

Additional details and impacted files
@@            Coverage Diff             @@
##           master    #5141      +/-   ##
==========================================
- Coverage   91.22%   91.21%   -0.01%     
==========================================
  Files         114      114              
  Lines        8852     8865      +13     
==========================================
+ Hits         8075     8086      +11     
- Misses        777      779       +2     
Flag Coverage Δ
backend 93.77% <100.00%> (-0.03%) ⬇️
frontend 87.51% <ø> (ø)

Flags with carried forward coverage won't be shown. Click here to find out more.

Components Coverage Δ
Accounts & Authentication 97.40% <ø> (ø)
Challenges Management 96.18% <100.00%> (-0.06%) ⬇️
Job Processing 89.82% <ø> (ø)
Participants & Teams 99.54% <ø> (ø)
Challenge Hosts 100.00% <ø> (ø)
Analytics 100.00% <ø> (ø)
Web Interface 100.00% <ø> (ø)
Frontend (Gulp) 87.51% <ø> (ø)
All Models 97.36% <ø> (ø)
All Views 100.00% <ø> (ø)
All Serializers 98.58% <ø> (ø)
Utility Functions 97.17% <100.00%> (-0.09%) ⬇️
Core Configuration 82.35% <ø> (ø)
Files with missing lines Coverage Δ
apps/challenges/aws_utils.py 98.66% <100.00%> (-0.20%) ⬇️
Files with missing lines Coverage Δ
apps/challenges/aws_utils.py 98.66% <100.00%> (-0.20%) ⬇️

Continue to review full report in Codecov by Harness.

Legend - Click here to learn more
Δ = absolute <relative> (impact), ø = not affected, ? = missing data
Powered by Codecov. Last update 1c59607...0bd75ac. Read the comment docs.

🚀 New features to boost your workflow:
  • 📦 JS Bundle Analysis: Save yourself from yourself by tracking and limiting bundle sizes in JS merges.

@RishabhJain2018
RishabhJain2018 merged commit d5c841f into master Jul 8, 2026
35 checks passed
@RishabhJain2018
RishabhJain2018 deleted the cursor/fix-worker-py39-image-resolution-d2c6 branch July 8, 2026 07:15
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants