PageRenderTime 41ms CodeModel.GetById 15ms RepoModel.GetById 1ms app.codeStats 0ms

/desktop/core/src/desktop/management/commands/runcpserver.py

https://github.com/jcrobak/hue
Python | 146 lines | 125 code | 4 blank | 17 comment | 1 complexity | 33ee6dadbf0884bd9ed1fe86f718923a MD5 | raw file
  1. #!/usr/bin/env python
  2. # Licensed to Cloudera, Inc. under one
  3. # or more contributor license agreements. See the NOTICE file
  4. # distributed with this work for additional information
  5. # regarding copyright ownership. Cloudera, Inc. licenses this file
  6. # to you under the Apache License, Version 2.0 (the
  7. # "License"); you may not use this file except in compliance
  8. # with the License. You may obtain a copy of the License at
  9. #
  10. # http://www.apache.org/licenses/LICENSE-2.0
  11. #
  12. # Unless required by applicable law or agreed to in writing, software
  13. # distributed under the License is distributed on an "AS IS" BASIS,
  14. # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
  15. # See the License for the specific language governing permissions and
  16. # limitations under the License.
  17. # a thirdparty project
  18. import sys, os, logging
  19. from django.core.management.base import BaseCommand
  20. from desktop import conf
  21. CPSERVER_HELP = r"""
  22. Run Hue using the CherryPy WSGI server.
  23. """
  24. CPSERVER_OPTIONS = {
  25. 'host': conf.HTTP_HOST.get(),
  26. 'port': conf.HTTP_PORT.get(),
  27. 'server_name': 'localhost',
  28. 'threads': conf.CHERRYPY_SERVER_THREADS.get(),
  29. 'daemonize': False, # supervisor does this for us
  30. 'workdir': None,
  31. 'pidfile': None,
  32. 'server_user': conf.SERVER_USER.get(),
  33. 'server_group': conf.SERVER_GROUP.get(),
  34. 'ssl_certificate': conf.SSL_CERTIFICATE.get(),
  35. 'ssl_private_key': conf.SSL_PRIVATE_KEY.get()
  36. }
  37. class Command(BaseCommand):
  38. help = "CherryPy Server for Desktop."
  39. args = ""
  40. def handle(self, *args, **options):
  41. from django.conf import settings
  42. from django.utils import translation
  43. if not conf.ENABLE_CHERRYPY_SERVER.get():
  44. logging.info("Desktop is configured to not start CherryPy server.")
  45. sys.exit(0)
  46. # Activate the current language, because it won't get activated later.
  47. try:
  48. translation.activate(settings.LANGUAGE_CODE)
  49. except AttributeError:
  50. pass
  51. runcpserver(args)
  52. def usage(self, subcommand):
  53. return CPSERVER_HELP
  54. def change_uid_gid(uid, gid=None):
  55. """Try to change UID and GID to the provided values.
  56. UID and GID are given as names like 'nobody' not integer.
  57. Src: http://mail.mems-exchange.org/durusmail/quixote-users/4940/1/
  58. """
  59. if not os.geteuid() == 0:
  60. # Do not try to change the gid/uid if not root.
  61. return
  62. (uid, gid) = get_uid_gid(uid, gid)
  63. os.setgid(gid)
  64. os.setuid(uid)
  65. def get_uid_gid(uid, gid=None):
  66. """Try to change UID and GID to the provided values.
  67. UID and GID are given as names like 'nobody' not integer.
  68. Src: http://mail.mems-exchange.org/durusmail/quixote-users/4940/1/
  69. """
  70. import pwd, grp
  71. uid, default_grp = pwd.getpwnam(uid)[2:4]
  72. if gid is None:
  73. gid = default_grp
  74. else:
  75. try:
  76. gid = grp.getgrnam(gid)[2]
  77. except KeyError:
  78. gid = default_grp
  79. return (uid, gid)
  80. def drop_privileges_if_necessary(options):
  81. if os.geteuid() == 0 and options['server_user'] and options['server_group']:
  82. #ensure the that the daemon runs as specified user
  83. change_uid_gid(options['server_user'], options['server_group'])
  84. def start_server(options):
  85. """
  86. Start CherryPy server
  87. """
  88. from desktop.lib.wsgiserver import CherryPyWSGIServer as Server
  89. from django.core.handlers.wsgi import WSGIHandler
  90. # Translogger wraps a WSGI app with Apache-style combined logging.
  91. server = Server(
  92. (options['host'], int(options['port'])),
  93. WSGIHandler(),
  94. int(options['threads']),
  95. options['server_name']
  96. )
  97. if options['ssl_certificate'] and options['ssl_private_key']:
  98. server.ssl_certificate = options['ssl_certificate']
  99. server.ssl_private_key = options['ssl_private_key']
  100. try:
  101. server.bind_server()
  102. drop_privileges_if_necessary(options)
  103. server.listen_and_loop()
  104. except KeyboardInterrupt:
  105. server.stop()
  106. def runcpserver(argset=[], **kwargs):
  107. # Get the options
  108. options = CPSERVER_OPTIONS.copy()
  109. options.update(kwargs)
  110. for x in argset:
  111. if "=" in x:
  112. k, v = x.split('=', 1)
  113. else:
  114. k, v = x, True
  115. options[k.lower()] = v
  116. if "help" in options:
  117. print CPSERVER_HELP
  118. return
  119. # Start the webserver
  120. print 'starting server with options %s' % options
  121. start_server(options)
  122. if __name__ == '__main__':
  123. runcpserver(sys.argv[1:])