parent
							
								
									e8b875f552
								
							
						
					
					
						commit
						147bca1648
					
				
							
								
								
									
										1
									
								
								Makefile
									
									
									
									
									
								
							
							
						
						
									
										1
									
								
								Makefile
									
									
									
									
									
								
							| @ -90,6 +90,7 @@ ADMIN_API_METHODS_SIMPLE = \ | |||||||
| 	admin.vm.volume.ListSnapshots \
 | 	admin.vm.volume.ListSnapshots \
 | ||||||
| 	admin.vm.volume.Resize \
 | 	admin.vm.volume.Resize \
 | ||||||
| 	admin.vm.volume.Revert \
 | 	admin.vm.volume.Revert \
 | ||||||
|  | 	admin.vm.Stats \
 | ||||||
| 	$(null) | 	$(null) | ||||||
| 
 | 
 | ||||||
| ifeq ($(OS),Linux) | ifeq ($(OS),Linux) | ||||||
|  | |||||||
| @ -1093,3 +1093,77 @@ class QubesAdminAPI(qubes.api.AbstractQubesAPI): | |||||||
|         self.fire_event_for_permission() |         self.fire_event_for_permission() | ||||||
| 
 | 
 | ||||||
|         self.dest.fire_event('firewall-changed') |         self.dest.fire_event('firewall-changed') | ||||||
|  | 
 | ||||||
|  |     def _send_stats_single(self, info_time, info, only_vm, filters, | ||||||
|  |             id_to_name_map): | ||||||
|  |         '''A single iteration of sending VM stats | ||||||
|  | 
 | ||||||
|  |         :param info_time: time of previous iteration | ||||||
|  |         :param info: information retrieved in previous iteration | ||||||
|  |         :param only_vm: send information only about this VM | ||||||
|  |         :param filters: filters to apply on stats before sending | ||||||
|  |         :param id_to_name_map: ID->VM name map, may be modified | ||||||
|  |         :return: tuple(info_time, info) - new information (to be passed to | ||||||
|  |         the next iteration) | ||||||
|  |         ''' | ||||||
|  | 
 | ||||||
|  |         (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], 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'])) | ||||||
|  | 
 | ||||||
|  |         return info_time, info | ||||||
|  | 
 | ||||||
|  |     @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 | ||||||
|  | 
 | ||||||
|  |         self.send_event(self.app, 'connection-established') | ||||||
|  | 
 | ||||||
|  |         info_time = None | ||||||
|  |         info = None | ||||||
|  |         id_to_name_map = {0: 'dom0'} | ||||||
|  |         try: | ||||||
|  |             while True: | ||||||
|  |                 info_time, info = self._send_stats_single(info_time, info, | ||||||
|  |                     only_vm, stats_filters, id_to_name_map) | ||||||
|  |                 yield from asyncio.sleep(self.app.stats_interval) | ||||||
|  |         except asyncio.CancelledError: | ||||||
|  |             # valid method to terminate this loop | ||||||
|  |             pass | ||||||
|  | |||||||
| @ -706,6 +706,11 @@ class Qubes(qubes.PropertyHolder): | |||||||
|         default=lambda app: app.default_pool, |         default=lambda app: app.default_pool, | ||||||
|         doc='Default storage pool for kernel volumes') |         doc='Default storage pool for kernel volumes') | ||||||
| 
 | 
 | ||||||
|  |     stats_interval = qubes.property('stats_interval', | ||||||
|  |         default=3, | ||||||
|  |         type=int, | ||||||
|  |         doc='Interval in seconds for VM stats reporting (memory, CPU usage)') | ||||||
|  | 
 | ||||||
|     # TODO #1637 #892 |     # TODO #1637 #892 | ||||||
|     check_updates_vm = qubes.property('check_updates_vm', |     check_updates_vm = qubes.property('check_updates_vm', | ||||||
|         type=bool, setter=qubes.property.bool, |         type=bool, setter=qubes.property.bool, | ||||||
|  | |||||||
		Loading…
	
		Reference in New Issue
	
	Block a user
	 Marek Marczykowski-Górecki
						Marek Marczykowski-Górecki