Fix saving 'updates-available' flag reported by TemplateBasedVM
Look for the first updateable template up in the template chain, instead of going just one level up. Especially this applies to DispVM -> AppVM -> TemplateVM case. If DispVM reports available updates, 'updates-available' flag should be set on relevant TemplateVM, not AppVM (*-dvm). Include test for the new case. Fixes QubesOS/qubes-issues#3736
This commit is contained in:
parent
18b0fa9db7
commit
bfb09f567f
@ -108,14 +108,20 @@ class QubesMiscAPI(qubes.api.AbstractQubesAPI):
|
||||
update_count = int(untrusted_update_count)
|
||||
del untrusted_update_count
|
||||
|
||||
# look for the nearest updateable VM up in the template chain
|
||||
updateable_template = getattr(self.src, 'template', None)
|
||||
while updateable_template is not None and \
|
||||
not updateable_template.updateable:
|
||||
updateable_template = getattr(updateable_template, 'template', None)
|
||||
|
||||
if self.src.updateable:
|
||||
# Just trust information from VM itself
|
||||
self.src.features['updates-available'] = bool(update_count)
|
||||
self.app.save()
|
||||
elif getattr(self.src, 'template', None) is not None:
|
||||
elif updateable_template is not None:
|
||||
# Hint about updates availability in template
|
||||
# If template is running - it will notify about updates itself
|
||||
if self.src.template.is_running():
|
||||
if updateable_template.is_running():
|
||||
return
|
||||
# Ignore no-updates info
|
||||
if update_count > 0:
|
||||
@ -123,6 +129,6 @@ class QubesMiscAPI(qubes.api.AbstractQubesAPI):
|
||||
# in the template - ignore info
|
||||
if self.src.storage.outdated_volumes:
|
||||
return
|
||||
self.src.template.features['updates-available'] = bool(
|
||||
updateable_template.features['updates-available'] = bool(
|
||||
update_count)
|
||||
self.app.save()
|
||||
|
@ -249,6 +249,7 @@ class TC_00_API_Misc(qubes.tests.QubesTestCase):
|
||||
response = self.call_mgmt_func(b'qubes.NotifyUpdates', payload=b'0\n')
|
||||
self.assertIsNone(response)
|
||||
self.assertEqual(self.tpl.mock_calls, [
|
||||
mock.call.updateable.__bool__(),
|
||||
mock.call.is_running(),
|
||||
])
|
||||
self.assertEqual(self.app.mock_calls, [])
|
||||
@ -262,6 +263,7 @@ class TC_00_API_Misc(qubes.tests.QubesTestCase):
|
||||
self.assertIsNone(response)
|
||||
self.assertEqual(self.src.mock_calls, [])
|
||||
self.assertEqual(self.tpl.mock_calls, [
|
||||
mock.call.updateable.__bool__(),
|
||||
mock.call.is_running(),
|
||||
mock.call.features.__setitem__('updates-available', True),
|
||||
])
|
||||
@ -277,6 +279,7 @@ class TC_00_API_Misc(qubes.tests.QubesTestCase):
|
||||
self.assertIsNone(response)
|
||||
self.assertEqual(self.src.mock_calls, [])
|
||||
self.assertEqual(self.tpl.mock_calls, [
|
||||
mock.call.updateable.__bool__(),
|
||||
mock.call.is_running(),
|
||||
])
|
||||
self.assertIsInstance(self.tpl.updates_available, mock.Mock)
|
||||
@ -290,8 +293,29 @@ class TC_00_API_Misc(qubes.tests.QubesTestCase):
|
||||
self.assertIsNone(response)
|
||||
self.assertEqual(self.src.mock_calls, [])
|
||||
self.assertEqual(self.tpl.mock_calls, [
|
||||
mock.call.updateable.__bool__(),
|
||||
mock.call.is_running(),
|
||||
])
|
||||
self.assertIsInstance(self.src.updates_available, mock.Mock)
|
||||
self.assertEqual(self.app.mock_calls, [])
|
||||
|
||||
def test_028_notify_updates_template_based_dispvm(self):
|
||||
self.dvm = self.src
|
||||
self.dvm.updateable = False
|
||||
self.srv = mock.NonCallableMagicMock(template=self.dvm)
|
||||
self.src.updateable = False
|
||||
self.src.template.is_running.return_value = False
|
||||
self.src.storage.outdated_volumes = []
|
||||
response = self.call_mgmt_func(b'qubes.NotifyUpdates', payload=b'1\n')
|
||||
self.assertIsNone(response)
|
||||
self.assertEqual(self.src.mock_calls, [])
|
||||
self.assertEqual(self.dvm.mock_calls, [])
|
||||
self.assertEqual(self.tpl.mock_calls, [
|
||||
mock.call.updateable.__bool__(),
|
||||
mock.call.is_running(),
|
||||
mock.call.features.__setitem__('updates-available', True),
|
||||
])
|
||||
self.assertIsInstance(self.src.updates_available, mock.Mock)
|
||||
self.assertEqual(self.app.mock_calls, [
|
||||
mock.call.save()
|
||||
])
|
||||
|
Loading…
Reference in New Issue
Block a user