-
-
Notifications
You must be signed in to change notification settings - Fork 182
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
[fix] Fixed updating template puts devices in perennial "modified" state #213 #787
Conversation
691ea08
to
09bdb41
Compare
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This is good, thanks!
I was testing on a device and we have a similar problem there, that is, some aspects of the device may be changed (eg: configuration variables) without having any impact on the configuration checksum, and for this reason the config status remains in "modified" state.
After looking at the code I think we could use a similar solution there and I think we should take advantage of this chance to proceed and fix the issue also on Device
!
211107f
to
5da473f
Compare
5da473f
to
7061f76
Compare
@@ -919,7 +919,7 @@ def _assert_applying_conf_test_command(mocked_exec): | |||
self.assertEqual(conf.status, 'applied') | |||
|
|||
with self.subTest('openwisp_config < 0.6.0a: exit_code 0'): | |||
conf.config = '{"interfaces": []}' | |||
conf.config = '{"interfaces": [{"name": "eth00","type": "ethernet"}]}' |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Empty fields are omitted when generating configuration. Hence, the checksum remained same throughout the test which led to a failing test case. I have updated the test case to avoid this issue.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
It looks good but there's a detail which is bugging me, please see my comment below.
@@ -766,7 +781,7 @@ def test_config_modified_sent(self): | |||
|
|||
def test_check_changes_query(self): | |||
config = self._create_config(organization=self._get_org()) | |||
with self.assertNumQueries(1): | |||
with self.assertNumQueries(8): |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Can you please track what these additional 7 queries are doing here?
I wonder if there's any inefficiency here, if there's any we have to create an issue to address it.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This is the previous version of the code for _check_changes
:
openwisp-controller/openwisp_controller/config/base/config.py
Lines 477 to 493 in f879e84
def _check_changes(self): | |
current = self._meta.model.objects.only( | |
'backend', 'config', 'context', 'status' | |
).get(pk=self.pk) | |
if self.backend != current.backend: | |
# storing old backend to send backend change signal after save | |
self._old_backend = current.backend | |
for attr in ['backend', 'config', 'context']: | |
if getattr(self, attr) == getattr(current, attr): | |
continue | |
if self.status != 'modified': | |
self.set_status_modified(save=False) | |
else: | |
# config modified signal is always sent | |
# regardless of the current status | |
self._send_config_modified_after_save = True | |
break |
Earlier, we fetched the configuration object from the database (using 1 query) and then compared each field individually for changes
In this patch, we generate the configuration to get the checksum
openwisp-controller/openwisp_controller/config/base/config.py
Lines 477 to 492 in 7061f76
def _check_changes(self): | |
current = self._meta.model.objects.only( | |
'backend', 'config', 'context', 'status' | |
).get(pk=self.pk) | |
if self.backend != current.backend: | |
# storing old backend to send backend change signal after save | |
self._old_backend = current.backend | |
if hasattr(self, 'backend_instance'): | |
del self.backend_instance | |
if self.checksum != current.checksum: | |
if self.status != 'modified': | |
self.set_status_modified(save=False) | |
else: | |
# config modified signal is always sent | |
# regardless of the current status | |
self._send_config_modified_after_save = True |
Generating the configuration requires additional queries (fetching templates, subnet division rules, etc.). Thus, we see an increase in the number of queries.
This method is only executed when the configuration object is saved.
The status of related Config objects will only be updated if the checksum of template's configuration changes.
Closes #213