Skip to content

[feature] Scheduled Mass Upgrades#460

Open
Eeshu-Yadav wants to merge 10 commits into
issues/417-persistence-schema-fieldsfrom
issues/380-scheduled-mass-upgrades
Open

[feature] Scheduled Mass Upgrades#460
Eeshu-Yadav wants to merge 10 commits into
issues/417-persistence-schema-fieldsfrom
issues/380-scheduled-mass-upgrades

Conversation

@Eeshu-Yadav

@Eeshu-Yadav Eeshu-Yadav commented Jun 30, 2026

Copy link
Copy Markdown
Contributor

Checklist

  • I have read the OpenWISP Contributing Guidelines.
  • I have manually tested the changes proposed in this pull request.
  • I have written new test cases for new code and/or updated existing tests for changes to existing code.
  • I have updated the documentation.

Reference to Existing Issue

Related to #380 (Scheduled Mass Upgrades, Phase 2).

This builds on the persistent-upgrades work, so for now it's based on issues/417-persistence-schema-fields and the diff only shows the scheduling changes. I'll retarget it to gsoc26-persistent-scheduled-upgrades once persistence merges.

Description of Changes

This adds the ability to schedule a mass upgrade for a later maintenance window instead of running it immediately, and to edit or cancel it while it waits.

The batch model gets a scheduled_at time, a stored firmwareless flag and a new scheduled status, with a (status, scheduled_at) index for the scan. When you pick a future time on the confirmation page, batch_upgrade() saves the batch as scheduled instead of dispatching it. A Celery Beat task, execute_scheduled_upgrades, then picks up batches whose time has come, re-checks that there are still devices to upgrade, and launches them; if nothing is eligible by then the batch is marked failed without touching a device.

To stop two upgrades from fighting over the same devices, creating a batch that overlaps an active one (or a device that is already mid-upgrade) is rejected, with the conflicting operation named in the error.

While a batch is scheduled you can change the time, the group/location filters, and the persistent and firmwareless options, or cancel it. This works both from the admin (Edit Schedule and Cancel buttons on the batch page) and from the REST API (reschedule/ and cancel/ endpoints); both go through the same code so they stay in sync. Times are entered in the browser timezone and converted to UTC on submit, the admin shows them back in the server timezone, and the API uses ISO 8601 with an offset.

Notifications go out when a scheduled upgrade starts, when it can't start because no devices are eligible, and when any mass upgrade finishes.

Two settings bound the schedule: OPENWISP_FIRMWARE_UPGRADER_SCHEDULE_MIN_DELAY (10 minutes) and OPENWISP_FIRMWARE_UPGRADER_SCHEDULE_MAX_HORIZON (180 days).

Docs are a new scheduled-mass-upgrades.rst page plus updates to the REST API, settings and changelog pages. Migrations are additive for both the default and the sample app, so existing rows need no data migration. Screenshots and the demo video are on the docs branch, like the persistent-upgrades ones.

Copilot AI review requested due to automatic review settings June 30, 2026 20:52
@coderabbitai

coderabbitai Bot commented Jun 30, 2026

Copy link
Copy Markdown

Important

Review skipped

Auto reviews are disabled on base/target branches other than the default branch.

Please check the settings in the CodeRabbit UI or the .coderabbit.yaml file in this repository. To trigger a single review, invoke the @coderabbitai review command.

⚙️ Run configuration

Configuration used: Organization UI

Review profile: ASSERTIVE

Plan: Pro

Run ID: d1c34ab2-2ff5-464e-9c9b-2436d847466e

You can disable this status message by setting the reviews.review_status to false in the CodeRabbit configuration file.

Use the checkbox below for a quick retry:

  • 🔍 Trigger review
✨ Finishing Touches
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Commit unit tests in branch issues/380-scheduled-mass-upgrades

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.

Copilot AI 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.

Pull request overview

This PR adds the schema and model-layer guardrails needed to support scheduled mass upgrades in openwisp-firmware-upgrader, extending BatchUpgradeOperation with scheduling metadata and a new pre-launch lifecycle state.

Changes:

  • Adds scheduled_at (nullable) and a persisted firmwareless flag to BatchUpgradeOperation.
  • Introduces a new scheduled batch status and a (status, scheduled_at) composite index for efficient due-batch scanning.
  • Extends model validation to enforce immutability rules across idlescheduledin-progress transitions, with accompanying tests and migrations.

Reviewed changes

Copilot reviewed 4 out of 4 changed files in this pull request and generated 3 comments.

File Description
openwisp_firmware_upgrader/base/models.py Adds new scheduling fields/status/index and validation guards for editability/immutability.
openwisp_firmware_upgrader/migrations/0020_batchupgradeoperation_firmwareless_and_more.py Applies the new fields/status/index to the main app via migration.
tests/openwisp2/sample_firmware_upgrader/migrations/0007_batchupgradeoperation_firmwareless_and_more.py Mirrors the same schema changes for the sample app migrations.
openwisp_firmware_upgrader/tests/test_models.py Adds tests covering defaults, status choice, composite index, and editability rules.

💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.

Comment thread openwisp_firmware_upgrader/base/models.py Outdated
Comment on lines +724 to +731
if self.build_id != build_id:
raise ValidationError(
{
"build": _(
"The build cannot be changed while a mass upgrade "
"is scheduled"
)
}
Comment thread openwisp_firmware_upgrader/tests/test_models.py
@Eeshu-Yadav
Eeshu-Yadav force-pushed the issues/380-scheduled-mass-upgrades branch 3 times, most recently from d86b9c2 to bc62848 Compare July 5, 2026 18:31


Add the scheduled_at and firmwareless fields, the scheduled status, a
composite (status, scheduled_at) index, and the clean() guards that keep a
scheduled batch editable until it launches.

Related to #380
@Eeshu-Yadav
Eeshu-Yadav force-pushed the issues/380-scheduled-mass-upgrades branch from 909f056 to 50cf023 Compare July 7, 2026 10:38
…er fork #380

Validate scheduled_at against the min-delay and max-horizon bounds, and
fork batch_upgrade() to save the batch as scheduled instead of dispatching
when a future time is given.

Related to #380
Scan for due scheduled batches, re-validate the device population at launch
time, and dispatch each eligible batch once.

Related to #380
Reject a new batch when an active batch or per-device operation already
covers the same device population.

Related to #380
Add the scheduled_at field to the confirmation form with browser-to-UTC
conversion, and show the schedule on the batch list and detail views.

Related to #380
Accept scheduled_at on the batch-upgrade endpoint, add reschedule and
cancel endpoints backed by a batch-level cancel(), and allow filtering and
ordering by scheduled_at.

Related to #380
@Eeshu-Yadav
Eeshu-Yadav force-pushed the issues/380-scheduled-mass-upgrades branch from 50cf023 to fa25626 Compare July 7, 2026 10:50
…380

Wire Edit Schedule and Cancel buttons on the batch detail page to the
reschedule and cancel endpoints.

Related to #380
Send bell notifications when a scheduled upgrade starts, fails
re-validation, or any mass upgrade reaches a terminal state.

Related to #380
Add the Scheduled Mass Upgrades page and document the new settings, REST
endpoints, and changelog entry.

Related to #380


Cover scheduled execution, the scheduled-plus-persistent recovery flow, and
the confirmation-page schedule widget.

Related to #380
@Eeshu-Yadav
Eeshu-Yadav force-pushed the issues/380-scheduled-mass-upgrades branch from fa25626 to fa00bc9 Compare July 7, 2026 17:42
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