special_component.py 4.8 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124
  1. # Copyright (C) 2011 Internet Systems Consortium, Inc. ("ISC")
  2. #
  3. # Permission to use, copy, modify, and distribute this software for any
  4. # purpose with or without fee is hereby granted, provided that the above
  5. # copyright notice and this permission notice appear in all copies.
  6. #
  7. # THE SOFTWARE IS PROVIDED "AS IS" AND INTERNET SYSTEMS CONSORTIUM
  8. # DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL
  9. # IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL
  10. # INTERNET SYSTEMS CONSORTIUM BE LIABLE FOR ANY SPECIAL, DIRECT,
  11. # INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING
  12. # FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT,
  13. # NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION
  14. # WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
  15. from isc.bind10.component import Component, BaseComponent
  16. import isc.bind10.sockcreator
  17. from bind10_config import LIBEXECPATH
  18. import os
  19. import isc.log
  20. class SockCreator(BaseComponent):
  21. """
  22. The socket creator component. Will start and stop the socket creator
  23. accordingly.
  24. Note: _creator shouldn't be reset explicitly once created. The
  25. underlying Popen object would then wait() the child process internally,
  26. which breaks the assumption of b10-init, who is expecting to see
  27. the process die in waitpid().
  28. """
  29. def __init__(self, process, b10_init, kind, address=None, params=None):
  30. BaseComponent.__init__(self, b10_init, kind)
  31. self.__creator = None
  32. def _start_internal(self):
  33. self._b10_init.curproc = 'b10-sockcreator'
  34. self.__creator = isc.bind10.sockcreator.Creator(LIBEXECPATH + ':' +
  35. os.environ['PATH'])
  36. self._b10_init.register_process(self.pid(), self)
  37. self._b10_init.set_creator(self.__creator)
  38. self._b10_init.log_started(self.pid())
  39. # We are now ready for switching user.
  40. self._b10_init.change_user()
  41. def _stop_internal(self):
  42. self.__creator.terminate()
  43. def name(self):
  44. return "Socket creator"
  45. def pid(self):
  46. """
  47. Pid of the socket creator. It is provided differently from a usual
  48. component.
  49. """
  50. return self.__creator.pid() if self.__creator else None
  51. def kill(self, forceful=False):
  52. # We don't really care about forceful here
  53. if self.__creator:
  54. self.__creator.kill()
  55. class Msgq(Component):
  56. """
  57. The message queue. Starting is passed to b10-init, stopping is not
  58. supported and we leave b10-init kill it by signal.
  59. """
  60. def __init__(self, process, b10_init, kind, address=None, params=None):
  61. Component.__init__(self, process, b10_init, kind, None, None,
  62. b10_init.start_msgq)
  63. def _stop_internal(self):
  64. """
  65. We can't really stop the message queue, as many processes may need
  66. it for their shutdown and it doesn't have a shutdown command anyway.
  67. But as it is stateless, it's OK to kill it.
  68. So we disable this method (as the only time it could be called is
  69. during shutdown) and wait for b10-init to kill it in the next shutdown
  70. step.
  71. This actually breaks the recommendation at Component we shouldn't
  72. override its methods one by one. This is a special case, because
  73. we don't provide a different implementation, we completely disable
  74. the method by providing an empty one. This can't hurt the internals.
  75. """
  76. pass
  77. class CfgMgr(Component):
  78. def __init__(self, process, b10_init, kind, address=None, params=None):
  79. Component.__init__(self, process, b10_init, kind, 'ConfigManager',
  80. None, b10_init.start_cfgmgr)
  81. class Auth(Component):
  82. def __init__(self, process, b10_init, kind, address=None, params=None):
  83. Component.__init__(self, process, b10_init, kind, 'Auth', None,
  84. b10_init.start_auth)
  85. class Resolver(Component):
  86. def __init__(self, process, b10_init, kind, address=None, params=None):
  87. Component.__init__(self, process, b10_init, kind, 'Resolver', None,
  88. b10_init.start_resolver)
  89. class CmdCtl(Component):
  90. def __init__(self, process, b10_init, kind, address=None, params=None):
  91. Component.__init__(self, process, b10_init, kind, 'Cmdctl', None,
  92. b10_init.start_cmdctl)
  93. def get_specials():
  94. """
  95. List of specially started components. Each one should be the class than can
  96. be created for that component.
  97. """
  98. return {
  99. 'sockcreator': SockCreator,
  100. 'msgq': Msgq,
  101. 'cfgmgr': CfgMgr,
  102. # TODO: Should these be replaced by configuration in config manager only?
  103. # They should not have any parameters anyway
  104. 'auth': Auth,
  105. 'resolver': Resolver,
  106. 'cmdctl': CmdCtl
  107. }