diff --git a/Makefile b/Makefile index d871570e..df64f81e 100644 --- a/Makefile +++ b/Makefile @@ -109,6 +109,7 @@ ADMIN_API_METHODS_SIMPLE = \ admin.vm.volume.Set.revisions_to_keep \ admin.vm.volume.Set.rw \ admin.vm.Stats \ + admin.vm.CurrentState \ $(null) ifeq ($(OS),Linux) diff --git a/qubes/api/admin.py b/qubes/api/admin.py index 678cb98a..17a3ecd8 100644 --- a/qubes/api/admin.py +++ b/qubes/api/admin.py @@ -1677,3 +1677,18 @@ class QubesAdminAPI(qubes.api.AbstractQubesAPI): except asyncio.CancelledError: # valid method to terminate this loop pass + + @qubes.api.method('admin.vm.CurrentState', no_payload=True, + scope='local', read=True) + @asyncio.coroutine + def vm_current_state(self): + self.enforce(not self.arg) + self.fire_event_for_permission() + + state = { + 'mem': self.dest.get_mem(), + 'mem_static_max': self.dest.get_mem_static_max(), + 'cputime': self.dest.get_cputime(), + 'power_state': self.dest.get_power_state(), + } + return ' '.join('{}={}'.format(k, v) for k, v in state.items()) diff --git a/qubes/tests/api_admin.py b/qubes/tests/api_admin.py index a35a1b64..0cd6faa2 100644 --- a/qubes/tests/api_admin.py +++ b/qubes/tests/api_admin.py @@ -2614,6 +2614,20 @@ netvm default=True type=vm value = self.call_mgmt_func(b'admin.pool.volume.List', b'dom0', b'pool1') self.assertEqual(value, 'vol1\nvol2\n') + def test_800_current_state_default(self): + value = self.call_mgmt_func(b'admin.vm.CurrentState', b'test-vm1') + self.assertEqual( + value, 'mem=0 mem_static_max=0 cputime=0 power_state=Halted') + + def test_801_current_state_changed(self): + self.vm.get_mem = lambda: 512 + self.vm.get_mem_static_max = lambda: 1024 + self.vm.get_cputime = lambda: 100 + self.vm.get_power_state = lambda: 'Running' + value = self.call_mgmt_func(b'admin.vm.CurrentState', b'test-vm1') + self.assertEqual( + value, 'mem=512 mem_static_max=1024 cputime=100 power_state=Running') + def test_990_vm_unexpected_payload(self): methods_with_no_payload = [ b'admin.vm.List', diff --git a/qubes/vm/adminvm.py b/qubes/vm/adminvm.py index 46871b7b..a1b32ee5 100644 --- a/qubes/vm/adminvm.py +++ b/qubes/vm/adminvm.py @@ -160,6 +160,18 @@ class AdminVM(qubes.vm.BaseVM): self.log.warning('Failed to get memory limit for dom0: %s', e) return 4096 + def get_cputime(self): + '''Get total CPU time burned by Dom0 since start. + + .. seealso: + :py:meth:`qubes.vm.qubesvm.QubesVM.get_cputime` + ''' + try: + return self.libvirt_domain.info()[4] + except libvirt.libvirtError as e: + self.log.warning('Failed to get CPU time for dom0: %s', e) + return 0 + def verify_files(self): '''Always :py:obj:`True`