[docs] GSoC26: added "Persistent & Scheduled Firmware Upgrades" project idea.#268
Conversation
WalkthroughThis change adds two new detailed sections to the GSOC ideas documentation for OpenWISP Firmware Upgrader, covering Persistent Mass Upgrades and Scheduled Mass Upgrades. Each section outlines feature goals, high-level requirements, design considerations, integration points, UI/UX expectations, error handling, notification strategies, Celery integration, and testing requirements. The same content structure and details are documented twice within the file, with a total of 161 lines added to the RST documentation. Estimated code review effort🎯 2 (Simple) | ⏱️ ~10 minutes Possibly related PRs
🚥 Pre-merge checks | ✅ 2✅ Passed checks (2 passed)
✏️ Tip: You can configure your own custom pre-merge checks in the settings. ✨ Finishing touches🧪 Generate unit tests (beta)
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. Comment |
There was a problem hiding this comment.
Actionable comments posted: 2
🤖 Fix all issues with AI agents
In `@developer/gsoc-ideas-2026.rst`:
- Around line 1042-1202: The RST image directive referencing
'../images/gsoc/ideas/2023/firmware.jpg' inside the "Persistent & Scheduled
Firmware Upgrades" section is broken; either add the missing image file at that
path in the repo or update the image directive to point to an existing image.
Locate the image directive string '../images/gsoc/ideas/2023/firmware.jpg' in
developer/gsoc-ideas-2026.rst (under the "Persistent & Scheduled Firmware
Upgrades" heading) and either commit the correct image file to that images
folder or change the path to the correct existing image filename, then verify
Sphinx builds without missing-file warnings.
- Line 1046: Replace the outdated image directive string ".. image::
../images/gsoc/ideas/2023/firmware.jpg" with the 2026 image path ".. image::
../images/gsoc/ideas/2026/firmware-upgrader-openwrt-image-metadata-extraction.webp"
so the document references the correct 2026 firmware-upgrader image; locate the
exact directive line matching the original string and update it to the new path.
📜 Review details
Configuration used: Organization UI
Review profile: CHILL
Plan: Pro
📒 Files selected for processing (1)
developer/gsoc-ideas-2026.rst
⏰ Context from checks skipped due to timeout of 90000ms. You can increase the timeout in your CodeRabbit configuration to a maximum of 15 minutes (900000ms). (1)
- GitHub Check: build
✏️ Tip: You can disable this entire section by setting review_details to false in your review settings.
|
|
||
| Persistent & Scheduled Firmware Upgrades | ||
| ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ | ||
|
|
||
| .. image:: ../images/gsoc/ideas/2023/firmware.jpg | ||
|
|
||
| .. important:: | ||
|
|
||
| Languages and technologies used: **Python**, **Django**, **Celery**, | ||
| **REST API**, **JavaScript**. | ||
|
|
||
| **Mentors**: *Federico Capoano*, *TBA*. | ||
|
|
||
| **Project size**: 350 hours. | ||
|
|
||
| **Difficulty rate**: medium. | ||
|
|
||
| This project aims to enhance `OpenWISP Firmware Upgrader | ||
| <https://github.com/openwisp/openwisp-firmware-upgrader>`__ with two | ||
| complementary features that improve reliability and operational | ||
| flexibility for mass firmware upgrades: **persistent retries** for offline | ||
| devices (`#379 | ||
| <https://github.com/openwisp/openwisp-firmware-upgrader/issues/379>`__) | ||
| and **scheduled execution** for planned maintenance windows (`#380 | ||
| <https://github.com/openwisp/openwisp-firmware-upgrader/issues/380>`__). | ||
|
|
||
| Currently, firmware upgrades in OpenWISP happen immediately via Celery | ||
| tasks. If a device is offline at the moment of upgrade, the task fails and | ||
| requires manual retry. In large deployments, this becomes unmanageable. | ||
| Additionally, network operators need the ability to schedule upgrades | ||
| during low-usage windows without manual intervention at execution time. | ||
|
|
||
| Expected outcomes | ||
| +++++++++++++++++ | ||
|
|
||
| Introduce support for **persistent mass upgrades** that automatically | ||
| retry for offline devices and **scheduled mass upgrades** that execute at | ||
| a user-defined future time. | ||
|
|
||
| 1. **Persistent mass upgrades** (`#379 | ||
| <https://github.com/openwisp/openwisp-firmware-upgrader/issues/379>`__) | ||
|
|
||
| Mass upgrade operations should be able to retry indefinitely for | ||
| devices that are offline at the initial execution time. | ||
|
|
||
| - Add a ``persistent`` boolean field to mass upgrade operations | ||
| (visible in admin and REST API, checked by default, immutable after | ||
| creation). | ||
| - Track retry count and scheduled retry time in the | ||
| ``UpgradeOperation`` model. | ||
| - Implement **device online detection**: | ||
|
|
||
| - Prefer using the ``health_status_changed`` signal from OpenWISP | ||
| Monitoring (with mocking for testing). | ||
| - Fallback: periodic retries with randomized exponential backoff | ||
| (configurable, max once every 12 hours). | ||
|
|
||
| - Implement **retry strategy**: | ||
|
|
||
| - Randomized exponential backoff with indefinite retries. | ||
| - Periodic reminders (default every 2 months) via | ||
| ``generic_notification`` to admins about devices still pending | ||
| upgrade, with links filtering pending devices. | ||
| - Continue until admin cancels or all devices are upgraded. | ||
|
|
||
| - **Integration with Celery**: Use a new Celery task to "wake up" | ||
| pending upgrades, with randomized delays to prevent system overload. | ||
| - **Failure handling**: Use ``generic_notification`` for failures | ||
| requiring attention (devices offline too long, upgrade errors). | ||
| - **Edge cases**: Handle concurrent signal triggers, ensure only one | ||
| upgrade per device, no rollback support needed. | ||
|
|
||
| 2. **Scheduled mass upgrades** (`#380 | ||
| <https://github.com/openwisp/openwisp-firmware-upgrader/issues/380>`__) | ||
|
|
||
| Allow users to schedule mass upgrades for future execution. | ||
|
|
||
| - **UI**: Add optional datetime scheduling on mass upgrade confirmation | ||
| page. Default is immediate execution unless a future datetime is set. | ||
| - **Validation**: Scheduled datetime must be: | ||
|
|
||
| - In the future | ||
| - Respect minimum delay (e.g., 10 minutes) | ||
| - Not exceed maximum horizon (e.g., 6 months) | ||
|
|
||
| - **Timezone handling**: User input in browser timezone, storage in | ||
| UTC, server timezone clearly indicated in UI. | ||
| - **Status model**: Extend to include ``scheduled`` state with | ||
| transitions: scheduled → running, scheduled → canceled, scheduled → | ||
| failed. | ||
| - **Execution model**: Use Celery Beat periodic task (every minute) to | ||
| scan and execute due upgrades. **Avoid Celery eta/countdown** for | ||
| reliability with far-future tasks. | ||
| - **Runtime validation**: Re-evaluate devices, permissions, firmware | ||
| availability at execution time. Cancel with error if all targets | ||
| become invalid. | ||
| - **Conflict prevention**: Prevent creating conflicting mass upgrades | ||
| (scheduled or immediate) when one is already pending. | ||
| - **Notifications**: Send ``generic_notification`` when scheduled | ||
| upgrades start and complete. | ||
|
|
||
| 3. **Combined features** | ||
|
|
||
| Scheduled upgrades should also support persistence. A scheduled upgrade | ||
| that starts but has offline devices should continue retrying according | ||
| to the persistence logic. | ||
|
|
||
| 4. **General requirements** | ||
|
|
||
| - Operations editable only while in ``scheduled`` status. | ||
| - Clear exposure of scheduled status and datetime in admin list, detail | ||
| view, and REST API. | ||
| - Full feature parity between Django admin and REST API. | ||
|
|
||
| 5. **Testing and documentation** | ||
|
|
||
| - Test coverage **must not decrease** from current levels. | ||
| - **Browser tests** for the scheduling UI and admin interface workflows | ||
| are required. | ||
| - Documentation has to be kept up to date, including: | ||
|
|
||
| - Usage instructions for persistent and scheduled upgrades. | ||
| - Updated screenshots reflecting UI changes. | ||
| - One short example usage video per each feature. | ||
|
|
||
| Prerequisites to work on this project | ||
| +++++++++++++++++++++++++++++++++++++ | ||
|
|
||
| Applicants must demonstrate a solid understanding of: | ||
|
|
||
| - **Python**, **Django**, and **JavaScript**. | ||
| - REST APIs and background task processing (Celery, Celery Beat). | ||
| - Timezone handling and datetime management. | ||
| - Experience with `OpenWISP Firmware Upgrader | ||
| <https://github.com/openwisp/openwisp-firmware-upgrader>`__ is | ||
| essential. Contributions or resolved issues in this repository are | ||
| considered strong evidence of the required proficiency. | ||
|
|
||
| Open questions for contributors | ||
| +++++++++++++++++++++++++++++++ | ||
|
|
||
| 1. **Persistence implementation**: What is the optimal database schema for | ||
| tracking persistent upgrade state while maintaining compatibility with | ||
| existing upgrade operation models? | ||
| 2. **Scheduling mechanism**: How exactly should the Celery Beat periodic | ||
| task be configured to reliably detect and execute due scheduled | ||
| upgrades without performance issues? | ||
| 3. **Timezone UX**: What is the best way to handle timezone display and | ||
| input in the admin interface to minimize user confusion? | ||
| 4. **Backoff strategy**: What are the optimal parameters for randomized | ||
| exponential backoff (initial delay, max delay, randomization factor)? | ||
| 5. **Conflict detection**: How should conflicting operations be detected | ||
| and prevented? What defines a "conflict"? | ||
| 6. **Monitoring integration**: How exactly should the | ||
| ``health_status_changed`` signal from OpenWISP Monitoring be integrated | ||
| for optimal online detection? | ||
| 7. **Notification frequency**: What are the optimal default periods for | ||
| reminder notifications about pending persistent upgrades? | ||
| 8. **Edge case handling**: How should edge cases be handled, such as | ||
| devices that are offline for months, or mass upgrades with very large | ||
| device counts? |
There was a problem hiding this comment.
🧩 Analysis chain
🏁 Script executed:
#!/bin/bash
# Check for duplicates of the section title
echo "=== Searching for section title occurrences ==="
rg -n "Persistent & Scheduled Firmware Upgrades" developer/gsoc-ideas-2026.rst
echo ""
echo "=== File line count ==="
wc -l developer/gsoc-ideas-2026.rst
echo ""
echo "=== Checking if image file exists ==="
ls -la developer/images/gsoc/ideas/2023/firmware.jpg 2>&1 || echo "2023 image not found"
ls -la developer/images/gsoc/ideas/2026/firmware.jpg 2>&1 || echo "2026 image not found"
ls -la developer/images/gsoc/ideas/firmware.jpg 2>&1 || echo "Generic firmware image not found"
echo ""
echo "=== Checking context around lines 1042-1046 ==="
sed -n '1040,1050p' developer/gsoc-ideas-2026.rstRepository: openwisp/openwisp-docs
Length of output: 960
Fix broken image reference: the image file does not exist at the specified path.
The reference ../images/gsoc/ideas/2023/firmware.jpg at line 1046 points to a non-existent file. The image must be either:
- Added to the correct location in the repository, or
- The path corrected to point to an existing image file
Verify the correct image path or provide the missing image file before merging.
🤖 Prompt for AI Agents
In `@developer/gsoc-ideas-2026.rst` around lines 1042 - 1202, The RST image
directive referencing '../images/gsoc/ideas/2023/firmware.jpg' inside the
"Persistent & Scheduled Firmware Upgrades" section is broken; either add the
missing image file at that path in the repo or update the image directive to
point to an existing image. Locate the image directive string
'../images/gsoc/ideas/2023/firmware.jpg' in developer/gsoc-ideas-2026.rst (under
the "Persistent & Scheduled Firmware Upgrades" heading) and either commit the
correct image file to that images folder or change the path to the correct
existing image filename, then verify Sphinx builds without missing-file
warnings.
There was a problem hiding this comment.
🧩 Analysis chain
🏁 Script executed:
#!/bin/bash
# Check if the image exists at the correct resolved path
echo "=== Checking image at correct resolved path ==="
if [ -f "images/gsoc/ideas/2023/firmware.jpg" ]; then
echo "✓ Image exists at: images/gsoc/ideas/2023/firmware.jpg"
ls -lh images/gsoc/ideas/2023/firmware.jpg
else
echo "✗ Image not found at: images/gsoc/ideas/2023/firmware.jpg"
fi
echo ""
echo "=== Listing contents of images/gsoc/ideas/2023/ ==="
ls -la images/gsoc/ideas/2023/ 2>&1 || echo "Directory does not exist"
echo ""
echo "=== Verifying relative path resolution ==="
echo "RST file location: developer/gsoc-ideas-2026.rst"
echo "Relative reference: ../images/gsoc/ideas/2023/firmware.jpg"
echo "Resolves to: images/gsoc/ideas/2023/firmware.jpg (from repo root)"
Length of output: 719
@nemesifier, you're absolutely right—I apologize for the incorrect flag. The image does exist at images/gsoc/ideas/2023/firmware.jpg and the relative reference ../images/gsoc/ideas/2023/firmware.jpg from developer/gsoc-ideas-2026.rst resolves correctly to this file. My initial script checked an incorrect path. The image reference is valid. ✓
| Persistent & Scheduled Firmware Upgrades | ||
| ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ | ||
|
|
||
| .. image:: ../images/gsoc/ideas/2023/firmware.jpg |
There was a problem hiding this comment.
🧩 Analysis chain
🏁 Script executed:
#!/bin/bash
# Check if the 2023 image exists
echo "=== Checking for firmware.jpg in images/gsoc/ideas/ ==="
fd -t f "firmware.jpg" images/gsoc/ideas/
# Check directory structure
echo ""
echo "=== Directory structure of images/gsoc/ideas/ ==="
fd -t d . images/gsoc/ideas/ 2>/dev/null | head -20
# List all files in 2023 directory if it exists
echo ""
echo "=== Files in images/gsoc/ideas/2023/ if it exists ==="
ls -la images/gsoc/ideas/2023/ 2>/dev/null || echo "Directory does not exist"
# List all files in 2026 directory if it exists
echo ""
echo "=== Files in images/gsoc/ideas/2026/ if it exists ==="
ls -la images/gsoc/ideas/2026/ 2>/dev/null || echo "Directory does not exist"
# Check for any year-named directories
echo ""
echo "=== Year-based directories in images/gsoc/ideas/ ==="
ls -d images/gsoc/ideas/20*/ 2>/dev/null || echo "No year-based directories found"Repository: openwisp/openwisp-docs
Length of output: 1119
🏁 Script executed:
#!/bin/bash
# Read context around line 1046 to see the project idea
echo "=== Context around line 1046 in developer/gsoc-ideas-2026.rst ==="
sed -n '1030,1070p' developer/gsoc-ideas-2026.rst
# Also check if there are other 2023 image references in the 2026 file
echo ""
echo "=== All image references in developer/gsoc-ideas-2026.rst ==="
grep -n "image::" developer/gsoc-ideas-2026.rstRepository: openwisp/openwisp-docs
Length of output: 2316
Update image path to use 2026 version
The image path at line 1046 references ../images/gsoc/ideas/2023/firmware.jpg but this is a 2026 project idea document. The correct 2026 firmware-upgrader image exists at ../images/gsoc/ideas/2026/firmware-upgrader-openwrt-image-metadata-extraction.webp and should be used instead.
Change line 1046 from:
.. image:: ../images/gsoc/ideas/2023/firmware.jpg
to:
.. image:: ../images/gsoc/ideas/2026/firmware-upgrader-openwrt-image-metadata-extraction.webp
🤖 Prompt for AI Agents
In `@developer/gsoc-ideas-2026.rst` at line 1046, Replace the outdated image
directive string ".. image:: ../images/gsoc/ideas/2023/firmware.jpg" with the
2026 image path ".. image::
../images/gsoc/ideas/2026/firmware-upgrader-openwrt-image-metadata-extraction.webp"
so the document references the correct 2026 firmware-upgrader image; locate the
exact directive line matching the original string and update it to the new path.
There was a problem hiding this comment.
@nemesifier, understood! I'll keep the existing image reference.
🐰
GSoC26: added "Persistent & Scheduled Firmware Upgrades" project idea.