Skip to content

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

@Eeshu-Yadav

Description

@Eeshu-Yadav

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.

Metadata

Metadata

Assignees

Labels

enhancementNew feature or requestgsoc-ideaIssues part of Google Summer of Code project

Type

No fields configured for Task.

Projects

Status
ToDo

Milestone

No milestone

Relationships

None yet

Development

No branches or pull requests

Issue actions