Skip to content

Commit

Permalink
features: add check_with_netvm, similar to check_with_template
Browse files Browse the repository at this point in the history
Allow using default feature value from netvm, not template. This makes
sense for network-related features like using tor, supporting ipv6 etc.

Similarly to check_with_template, expose it also on Admin API.
  • Loading branch information
marmarek committed Dec 1, 2017
1 parent e194858 commit 315d383
Show file tree
Hide file tree
Showing 4 changed files with 57 additions and 0 deletions.
1 change: 1 addition & 0 deletions Makefile
Original file line number Diff line number Diff line change
Expand Up @@ -69,6 +69,7 @@ ADMIN_API_METHODS_SIMPLE = \
admin.vm.device.mic.Detach \
admin.vm.device.mic.List \
admin.vm.device.mic.Set.persistent \
admin.vm.feature.CheckWithNetvm \
admin.vm.feature.CheckWithTemplate \
admin.vm.feature.Get \
admin.vm.feature.List \
Expand Down
13 changes: 13 additions & 0 deletions qubes/api/admin.py
Original file line number Diff line number Diff line change
Expand Up @@ -883,6 +883,19 @@ def vm_feature_checkwithtemplate(self):
raise qubes.exc.QubesFeatureNotFoundError(self.dest, self.arg)
return value

@qubes.api.method('admin.vm.feature.CheckWithNetvm', no_payload=True,
scope='local', read=True)
@asyncio.coroutine
def vm_feature_checkwithnetvm(self):
# validation of self.arg done by qrexec-policy is enough

self.fire_event_for_permission()
try:
value = self.dest.features.check_with_netvm(self.arg)
except KeyError:
raise qubes.exc.QubesFeatureNotFoundError(self.dest, self.arg)
return value

@qubes.api.method('admin.vm.feature.Remove', no_payload=True,
scope='local', write=True)
@asyncio.coroutine
Expand Down
29 changes: 29 additions & 0 deletions qubes/tests/api_admin.py
Original file line number Diff line number Diff line change
Expand Up @@ -90,6 +90,10 @@ def tearDown(self):
self.base_dir_patch.stop()
if os.path.exists(self.test_base_dir):
shutil.rmtree(self.test_base_dir)
try:
del self.netvm
except AttributeError:
pass
del self.vm
del self.template
self.app.close()
Expand Down Expand Up @@ -1047,6 +1051,31 @@ def test_312_feature_checkwithtemplate_none(self):
b'test-vm1', b'test-feature')
self.assertFalse(self.app.save.called)

def test_315_feature_checkwithnetvm(self):
self.vm.features['test-feature'] = 'some-value'
value = self.call_mgmt_func(b'admin.vm.feature.CheckWithNetvm',
b'test-vm1', b'test-feature')
self.assertEqual(value, 'some-value')
self.assertFalse(self.app.save.called)

def test_316_feature_checkwithnetvm_netvm(self):
self.netvm = self.app.add_new_vm('AppVM', label='red',
name='test-netvm1',
template='test-template',
provides_network=True)
self.vm.netvm = self.netvm
self.netvm.features['test-feature'] = 'some-value'
value = self.call_mgmt_func(b'admin.vm.feature.CheckWithNetvm',
b'test-vm1', b'test-feature')
self.assertEqual(value, 'some-value')
self.assertFalse(self.app.save.called)

def test_317_feature_checkwithnetvm_none(self):
with self.assertRaises(qubes.exc.QubesFeatureNotFoundError):
self.call_mgmt_func(b'admin.vm.feature.CheckWithNetvm',
b'test-vm1', b'test-feature')
self.assertFalse(self.app.save.called)

def test_320_feature_set(self):
value = self.call_mgmt_func(b'admin.vm.feature.Set',
b'test-vm1', b'test-feature', b'some-value')
Expand Down
14 changes: 14 additions & 0 deletions qubes/vm/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -186,6 +186,20 @@ def check_with_template(self, feature, default=_NO_DEFAULT):

return default

def check_with_netvm(self, feature, default=_NO_DEFAULT):
''' Check if the vm's netvm has the specified feature. '''
if feature in self:
return self[feature]

if hasattr(self.vm, 'netvm') and self.vm.netvm is not None:
return self.vm.netvm.features.check_with_netvm(feature,
default)

if default is self._NO_DEFAULT:
raise KeyError(feature)

return default


class Tags(set):
'''Manager of the tags.
Expand Down

0 comments on commit 315d383

Please sign in to comment.