openwisp / openwisp/docker-openwisp

[chores:gsoc26] Wire openwisp-firmware-upgrader's check_pending_upgrades into the docker-openwisp Beat schedule

Open
#623 1 comment 0 reactions 1 assignee View on GitHub

@Eeshu-Yadav is already working on this.

Since Jun 2, 2026.

enhancement gsoc-idea
Dominant language
Python
Stars
209
Forks
125
Avg merge
1d 4h
Merged PRs (30d)
24

Description

Is your feature request related to a problem? Please describe.

openwisp-firmware-upgrader is gaining a "persistent mass upgrades" feature (parent issue openwisp/openwisp-firmware-upgrader#379, implementation in PR #436). The feature introduces two new Celery Beat tasks:

  • openwisp_firmware_upgrader.tasks.check_pending_upgrades — scans for offline-device upgrades whose next_retry_at has elapsed and dispatches retry workers (recommended cadence: 10 minutes).
  • openwisp_firmware_upgrader.tasks.send_pending_upgrade_reminders — scans for long-running persistent batches and fires a generic_message notification when each batch's reminder cadence has elapsed (recommended scan cadence: 7 days; per-batch reminders every 60 days, configurable via OPENWISP_FIRMWARE_UPGRADER_PERSISTENT_REMINDER_PERIOD).

The package only registers these tasks in its own test settings. On a docker-openwisp install, images/common/openwisp/celery.py builds beat_schedule by merging per-module dicts (radius_schedule, topology_schedule, notification_schedule, monitoring_schedule, metric_collection_schedule), and there is no firmware_schedule to merge in — firmware-upgrader currently only contributes task_routes entries inside the USE_OPENWISP_FIRMWARE block at lines 34-42. Without this wiring, neither the retry loop nor the reminder notifications ever fire on docker installs.

Describe the solution I would implement

I would like to add the firmware_schedule block alongside the existing per-module schedules, mirroring how monitoring_schedule is wired today.

  1. In images/common/openwisp/celery.py:

    • Add firmware_schedule to the empty-dict init tuple at lines 10-15 (currently radius_schedule, topology_schedule, monitoring_schedule, metric_collection_schedule).
    • Inside the existing if env_bool(os.environ.get("USE_OPENWISP_FIRMWARE")) and env_bool(os.environ.get("USE_OPENWISP_CELERY_FIRMWARE")) block at lines 34-42, populate it:
      firmware_schedule = {
          "check_pending_upgrades": {
              "task": "openwisp_firmware_upgrader.tasks.check_pending_upgrades",
              "schedule": timedelta(
                  minutes=int(os.environ.get(
                      "OPENWISP_FIRMWARE_CHECK_PENDING_PERIOD_MINUTES", 10,
                  )),
              ),
          },
          "send_pending_upgrade_reminders": {
              "task": "openwisp_firmware_upgrader.tasks.send_pending_upgrade_reminders",
              "schedule": timedelta(
                  days=int(os.environ.get(
                      "OPENWISP_FIRMWARE_REMINDER_SCAN_PERIOD_DAYS", 7,
                  )),
              ),
          },
      }
      
    • Spread **firmware_schedule into the beat_schedule={...} argument at lines 90-96.
  2. In .env, the .env defaults block and the ENV lines in images/openwisp_base/Dockerfile:

    • Add both env vars alongside the existing USE_OPENWISP_FIRMWARE / USE_OPENWISP_CELERY_FIRMWARE block:
      OPENWISP_FIRMWARE_CHECK_PENDING_PERIOD_MINUTES=10
      OPENWISP_FIRMWARE_REMINDER_SCAN_PERIOD_DAYS=7
      
    • Defaults of 10 minutes and 7 days are the recommended cadences from the upstream feature design. Operators tuning for very large fleets can override them without rebuilding the image.
  3. In docs/user/settings.rst:

    • Document both env vars in the USE_OPENWISP_CELERY_FIRMWARE section around line 340, following the same shape as the existing OPENWISP_CELERY_FIRMWARE_COMMAND_FLAGS entry — one short paragraph each saying what it controls and what the default is.
  4. In tests/runtests.py:

    • The test_celery assertion at lines 340-412 iterates expected_output_list looking for every task the worker should have registered. The firmware section at lines 361-364 lists four tasks today. Add the three new ones:
      "openwisp_firmware_upgrader.tasks.check_pending_upgrades",
      "openwisp_firmware_upgrader.tasks.retry_pending_upgrade",
      "openwisp_firmware_upgrader.tasks.send_pending_upgrade_reminders",
      
    • retry_pending_upgrade isn't on the Beat schedule itself (it's only invoked by check_pending_upgrades.apply_async), but it does need to be registered on the worker so the dispatch lands somewhere, which is what test_celery checks for.

Tracked under the persistent-mass-upgrades parent in openwisp-firmware-upgrader so the docs PR there can link back here for deployers.

Contributor guide

Open the contributing guide

First steps

  1. Read the whole issue, then the project's contributing guide.
  2. Comment on the issue to say you are picking it up — it saves two people doing the same work.
  3. Fork the repository and make your change on a branch.
  4. Open a pull request that references the issue number.

Assessment

This issue has not been assessed yet.

Get new issues in your inbox

A short digest of beginner-friendly GitHub issues.