Skip to content

Commit

Permalink
api/admin: implement admin.vm.Stats
Browse files Browse the repository at this point in the history
  • Loading branch information
marmarek committed Jul 27, 2017
1 parent e8b875f commit 3ca0be1
Show file tree
Hide file tree
Showing 3 changed files with 58 additions and 0 deletions.
1 change: 1 addition & 0 deletions Makefile
Original file line number Diff line number Diff line change
Expand Up @@ -90,6 +90,7 @@ ADMIN_API_METHODS_SIMPLE = \
admin.vm.volume.ListSnapshots \
admin.vm.volume.Resize \
admin.vm.volume.Revert \
admin.vm.Stats \
$(null)

ifeq ($(OS),Linux)
Expand Down
52 changes: 52 additions & 0 deletions qubes/api/admin.py
Original file line number Diff line number Diff line change
Expand Up @@ -1093,3 +1093,55 @@ def vm_firewall_reload(self):
self.fire_event_for_permission()

self.dest.fire_event('firewall-changed')

@qubes.api.method('admin.vm.Stats', no_payload=True,
scope='global', read=True)
@asyncio.coroutine
def vm_stats(self):
assert not self.arg

# run until client connection is terminated
self.cancellable = True

# cache event filters, to not call an event each time an event arrives
stats_filters = self.fire_event_for_permission()

only_vm = None
if self.dest.name != 'dom0':
only_vm = self.dest

info_time = None
info = None
id_to_name_map = {0: 'dom0'}
while True:
(info_time, info) = self.app.host.get_vm_stats(info_time, info,
only_vm=only_vm)
for vm_id, vm_info in info.items():
if vm_id not in id_to_name_map:
try:
name = \
self.app.vmm.libvirt_conn.lookupByID(vm_id).name()
except libvirt.libvirtError as err:
if err.get_error_code() == libvirt.VIR_ERR_NO_DOMAIN:
# stubdomain or so
name = None
else:
raise
id_to_name_map[vm_id] = name
else:
name = id_to_name_map[vm_id]

# skip VMs with unknown name
if name is None:
continue

if not list(qubes.api.apply_filters([name],
stats_filters)):
continue

self.send_event(name, 'vm-stats',
memory_kb=int(vm_info['memory_kb']),
cpu_time=int(vm_info['cpu_time'] / 1000000),
cpu_usage=int(vm_info['cpu_usage']))

yield from asyncio.sleep(self.app.stats_update_interval)
5 changes: 5 additions & 0 deletions qubes/app.py
Original file line number Diff line number Diff line change
Expand Up @@ -706,6 +706,11 @@ class Qubes(qubes.PropertyHolder):
default=lambda app: app.default_pool,
doc='Default storage pool for kernel volumes')

stats_update_interval = qubes.property('stats_interval',
default=3,
type=int,
doc='Interval in seconds for VM stats reporting (memory, CPU usage)')

# TODO #1637 #892
check_updates_vm = qubes.property('check_updates_vm',
type=bool, setter=qubes.property.bool,
Expand Down

0 comments on commit 3ca0be1

Please sign in to comment.