utils.py 2.1 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768
  1. # -*- encoding: utf8 -*-
  2. #
  3. # The Qubes OS Project, http://www.qubes-os.org
  4. #
  5. # Copyright (C) 2017 Marek Marczykowski-Górecki
  6. # <marmarek@invisiblethingslab.com>
  7. #
  8. # This program is free software; you can redistribute it and/or modify
  9. # it under the terms of the GNU Lesser General Public License as published by
  10. # the Free Software Foundation; either version 2.1 of the License, or
  11. # (at your option) any later version.
  12. #
  13. # This program is distributed in the hope that it will be useful,
  14. # but WITHOUT ANY WARRANTY; without even the implied warranty of
  15. # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  16. # GNU Lesser General Public License for more details.
  17. #
  18. # You should have received a copy of the GNU Lesser General Public License along
  19. # with this program; if not, see <http://www.gnu.org/licenses/>.
  20. ''' Utilities for common events-based actions '''
  21. import asyncio
  22. import functools
  23. import qubesadmin.events
  24. import qubesadmin.exc
  25. class Interrupt(Exception):
  26. '''Interrupt events processing'''
  27. def interrupt_on_vm_shutdown(vms, subject, event):
  28. '''Interrupt events processing when given VM was shutdown'''
  29. # pylint: disable=unused-argument
  30. if event == 'connection-established':
  31. if all(vm.is_halted() for vm in sorted(vms)):
  32. raise Interrupt
  33. elif event == 'domain-shutdown' and subject in vms:
  34. vms.remove(subject)
  35. if not vms:
  36. raise Interrupt
  37. @asyncio.coroutine
  38. def wait_for_domain_shutdown(vms):
  39. ''' Helper function to wait for domain shutdown.
  40. This function wait for domain shutdown, but do not initiate the shutdown
  41. itself.
  42. :param vms: QubesVM object collection to wait for shutdown on
  43. '''
  44. if not vms:
  45. return
  46. app = list(vms)[0].app
  47. vms = set(vms)
  48. events = qubesadmin.events.EventsDispatcher(app, enable_cache=False)
  49. events.add_handler('domain-shutdown',
  50. functools.partial(interrupt_on_vm_shutdown, vms))
  51. events.add_handler('connection-established',
  52. functools.partial(interrupt_on_vm_shutdown, vms))
  53. try:
  54. yield from events.listen_for_events()
  55. except Interrupt:
  56. pass