Skip to content

Commit b0b93d6

Browse files
Codexclaude
andcommitted
[fix] Guard missing skip_push_update_on_save in register view #1331
DeviceRegisterView._update_device_name calls ``device.skip_push_update_on_save()`` whenever an agent re-registers with a hostname different from the MAC address. That method is referenced in the view but is not implemented on the Device model, so every such re-registration crashes with HTTP 500: AttributeError: 'Device' object has no attribute 'skip_push_update_on_save' This breaks the consistent_registration / factory-reset workflow: 1. A router does a factory reset → loses its local UUID/key 2. The agent computes ``consistent_key = md5(MAC + "+" + secret)`` and POSTs ``/controller/register/``. 3. OpenWISP looks up the existing device by the consistent key and finds it. 4. The view enters the ``_update_device_name`` branch (because the hostname ``<MAC>-fwr-unprovisioned`` differs from the bare MAC). 5. The bogus method call raises ``AttributeError`` and the server returns HTTP 500. 6. The agent sees a response without the X-Openwisp-Controller header (the 500 error page does not set it) and aborts. 7. After 6 crash retries procd kills the agent. The router never recovers from a factory reset until an admin manually deletes the existing device record. This affects every deployment that uses consistent_registration and runs agents with hostnames that do not equal the bare MAC (e.g. anything that names devices by location or status). Wrap the call in ``getattr`` so the registration path succeeds whether the helper method exists or not. The actual helper can be reintroduced later without changing this site; the guard is forward-compatible. Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
1 parent 2ecf5a1 commit b0b93d6

File tree

1 file changed

+9
-1
lines changed
  • openwisp_controller/config/controller

1 file changed

+9
-1
lines changed

openwisp_controller/config/controller/views.py

Lines changed: 9 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -550,7 +550,15 @@ def _update_device_name(self, request, device):
550550
normalized_name = name.replace(":", "").replace("-", "").lower()
551551
if normalized_name != normalized_mac:
552552
device.name = name
553-
device.skip_push_update_on_save()
553+
# NOTE: upstream openwisp-controller 1.2 calls
554+
# ``device.skip_push_update_on_save()`` here, but that method
555+
# was never implemented on the Device model, causing every
556+
# re-registration with a non-MAC hostname to crash with
557+
# AttributeError. We guard the call so missing methods don't
558+
# break factory-reset re-registration.
559+
skip = getattr(device, "skip_push_update_on_save", None)
560+
if callable(skip):
561+
skip()
554562

555563

556564
class GetVpnView(SingleObjectMixin, View):

0 commit comments

Comments
 (0)