Skip to content
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

Merged
merged 2 commits into from
Jul 12, 2023

Conversation

pandafy
Copy link
Member

@pandafy pandafy commented Jul 6, 2023

The status of related Config objects will only be updated if the checksum of template's configuration changes.

Closes #213

@pandafy pandafy force-pushed the issues/213-template-device-modified branch 2 times, most recently from 691ea08 to 09bdb41 Compare July 6, 2023 16:52
@coveralls
Copy link

coveralls commented Jul 7, 2023

Coverage Status

coverage: 98.905% (-0.001%) from 98.906% when pulling 7061f76 on issues/213-template-device-modified into f879e84 on master.

Copy link
Member

@nemesifier nemesifier left a 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!

…ate #213

The status of related Config objects will only be updated if
the checksum of template's configuration changes.

Closes #213
@pandafy pandafy force-pushed the issues/213-template-device-modified branch from 211107f to 5da473f Compare July 10, 2023 19:13
@pandafy pandafy force-pushed the issues/213-template-device-modified branch from 5da473f to 7061f76 Compare July 11, 2023 13:34
@@ -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"}]}'
Copy link
Member Author

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.

Copy link
Member

@nemesifier nemesifier left a 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):
Copy link
Member

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.

Copy link
Member Author

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:

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

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.

@nemesifier nemesifier merged commit 4eec323 into master Jul 12, 2023
@nemesifier nemesifier deleted the issues/213-template-device-modified branch July 12, 2023 15:15
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.

[bug] Setting template organization puts devices in perennial "modified" state
3 participants