diff --git a/qubes/tests/api_admin.py b/qubes/tests/api_admin.py index 9b5b3b54d..83cb1e837 100644 --- a/qubes/tests/api_admin.py +++ b/qubes/tests/api_admin.py @@ -211,6 +211,8 @@ def test_026_vm_property_get_default_bool(self): def test_027_vm_property_get_all(self): # any string property, test \n encoding self.vm.kernelopts = 'opt1\nopt2\nopt3\\opt4' + # let it have 'dns' property + self.vm.provides_network = True with unittest.mock.patch.object(self.vm, 'property_list') as list_mock: list_mock.return_value = [ self.vm.property_get_def('name'), @@ -223,11 +225,13 @@ def test_027_vm_property_get_all(self): self.vm.property_get_def('qrexec_timeout'), self.vm.property_get_def('qid'), self.vm.property_get_def('updateable'), + self.vm.property_get_def('dns'), ] value = self.call_mgmt_func(b'admin.vm.property.GetAll', b'test-vm1') self.maxDiff = None expected = '''debug default=True type=bool False default_user default=True type=str user +dns default=True type=str 10.139.1.1 10.139.1.2 klass default=True type=str AppVM label default=False type=label red name default=False type=str test-vm1 @@ -238,6 +242,29 @@ def test_027_vm_property_get_all(self): netvm default=True type=vm \n''' self.assertEqual(value, expected) + def test_028_vm_property_get_list(self): + self.vm.provides_network = True + value = self.call_mgmt_func( + b'admin.vm.property.Get', + b'test-vm1', + b'dns') + self.assertEqual(value, 'default=True type=str 10.139.1.1 10.139.1.2') + + def test_029_vm_property_get_list_none(self): + value = self.call_mgmt_func( + b'admin.vm.property.Get', + b'test-vm1', + b'dns') + self.assertEqual(value, 'default=True type=str ') + + def test_029_vm_property_get_list_default(self): + self.vm.provides_network = True + value = self.call_mgmt_func( + b'admin.vm.property.GetDefault', + b'test-vm1', + b'dns') + self.assertEqual(value, 'type=str 10.139.1.1 10.139.1.2') + def test_030_vm_property_set_vm(self): netvm = self.app.add_new_vm('AppVM', label='red', name='test-net', template='test-template', provides_network=True) diff --git a/qubes/vm/mix/net.py b/qubes/vm/mix/net.py index a7caee312..7919bd1bd 100644 --- a/qubes/vm/mix/net.py +++ b/qubes/vm/mix/net.py @@ -91,6 +91,16 @@ def _setter_provides_network(self, prop, value): return value +class StrSerializableTuple(tuple): + def __str__(self): + # verify it can be deserialized later(currently 'dns' + # property is the only using this, and it is safe) + if any(' ' in el for el in self): + raise ValueError( + 'space found in a list element {!r}'.format(self)) + return ' '.join(self) + + class NetVMMixin(qubes.events.Emitter): ''' Mixin containing network functionality ''' mac = qubes.property('mac', type=str, @@ -224,14 +234,14 @@ def connected_vms(self): # used in both # - @property + @qubes.stateless_property def dns(self): - '''Secondary DNS server set up for this domain.''' + '''DNS servers set up for this domain.''' if self.netvm is not None or self.provides_network: - return ( + return StrSerializableTuple(( '10.139.1.1', '10.139.1.2', - ) + )) return None