qubesd.py 2.1 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677
  1. #!/usr/bin/env python3.6
  2. import asyncio
  3. import os
  4. import signal
  5. import libvirtaio
  6. import qubes
  7. import qubes.api
  8. import qubes.api.admin
  9. import qubes.api.internal
  10. import qubes.api.misc
  11. import qubes.log
  12. import qubes.utils
  13. import qubes.vm.qubesvm
  14. def sighandler(loop, signame, servers):
  15. print('caught {}, exiting'.format(signame))
  16. for server in servers:
  17. server.close()
  18. loop.stop()
  19. parser = qubes.tools.QubesArgumentParser(description='Qubes OS daemon')
  20. parser.add_argument('--debug', action='store_true', default=False,
  21. help='Enable verbose error logging (all exceptions with full '
  22. 'tracebacks) and also send tracebacks to Admin API clients')
  23. def main(args=None):
  24. loop = asyncio.get_event_loop()
  25. libvirtaio.virEventRegisterAsyncIOImpl(loop=loop)
  26. try:
  27. args = parser.parse_args(args)
  28. except:
  29. loop.close()
  30. raise
  31. args.app.register_event_handlers()
  32. if args.debug:
  33. qubes.log.enable_debug()
  34. servers = loop.run_until_complete(qubes.api.create_servers(
  35. qubes.api.admin.QubesAdminAPI,
  36. qubes.api.internal.QubesInternalAPI,
  37. qubes.api.misc.QubesMiscAPI,
  38. app=args.app, debug=args.debug))
  39. socknames = []
  40. for server in servers:
  41. for sock in server.sockets:
  42. socknames.append(sock.getsockname())
  43. for signame in ('SIGINT', 'SIGTERM'):
  44. loop.add_signal_handler(getattr(signal, signame),
  45. sighandler, loop, signame, servers)
  46. qubes.utils.systemd_notify()
  47. # make sure children will not inherit this
  48. os.environ.pop('NOTIFY_SOCKET', None)
  49. try:
  50. loop.run_forever()
  51. loop.run_until_complete(asyncio.wait([
  52. server.wait_closed() for server in servers]))
  53. for sockname in socknames:
  54. try:
  55. os.unlink(sockname)
  56. except FileNotFoundError:
  57. args.app.log.warning(
  58. 'socket {} got unlinked sometime before shutdown'.format(
  59. sockname))
  60. finally:
  61. loop.close()
  62. if __name__ == '__main__':
  63. main()