cubicweb/pyramid/pyramidctl.py
author Laurent Peuch <cortex@worlddomination.be>
Wed, 24 Jul 2019 16:11:22 +0200
changeset 12780 8caa109dfe94
parent 12751 30b205676182
permissions -rw-r--r--
[debug] add in each html snippet from where it has been generated in the code Closes #17219704
Ignore whitespace changes - Everywhere: Within whitespace: At end of lines:
11967
83739be20fab [pyramid] Add a copyright and docstring to all modules
Denis Laxalde <denis.laxalde@logilab.fr>
parents: 11867
diff changeset
     1
# copyright 2017 LOGILAB S.A. (Paris, FRANCE), all rights reserved.
83739be20fab [pyramid] Add a copyright and docstring to all modules
Denis Laxalde <denis.laxalde@logilab.fr>
parents: 11867
diff changeset
     2
# copyright 2014-2016 UNLISH S.A.S. (Montpellier, FRANCE), all rights reserved.
83739be20fab [pyramid] Add a copyright and docstring to all modules
Denis Laxalde <denis.laxalde@logilab.fr>
parents: 11867
diff changeset
     3
#
83739be20fab [pyramid] Add a copyright and docstring to all modules
Denis Laxalde <denis.laxalde@logilab.fr>
parents: 11867
diff changeset
     4
# contact http://www.logilab.fr/ -- mailto:contact@logilab.fr
83739be20fab [pyramid] Add a copyright and docstring to all modules
Denis Laxalde <denis.laxalde@logilab.fr>
parents: 11867
diff changeset
     5
#
83739be20fab [pyramid] Add a copyright and docstring to all modules
Denis Laxalde <denis.laxalde@logilab.fr>
parents: 11867
diff changeset
     6
# This file is part of CubicWeb.
83739be20fab [pyramid] Add a copyright and docstring to all modules
Denis Laxalde <denis.laxalde@logilab.fr>
parents: 11867
diff changeset
     7
#
83739be20fab [pyramid] Add a copyright and docstring to all modules
Denis Laxalde <denis.laxalde@logilab.fr>
parents: 11867
diff changeset
     8
# CubicWeb is free software: you can redistribute it and/or modify it under the
83739be20fab [pyramid] Add a copyright and docstring to all modules
Denis Laxalde <denis.laxalde@logilab.fr>
parents: 11867
diff changeset
     9
# terms of the GNU Lesser General Public License as published by the Free
83739be20fab [pyramid] Add a copyright and docstring to all modules
Denis Laxalde <denis.laxalde@logilab.fr>
parents: 11867
diff changeset
    10
# Software Foundation, either version 2.1 of the License, or (at your option)
83739be20fab [pyramid] Add a copyright and docstring to all modules
Denis Laxalde <denis.laxalde@logilab.fr>
parents: 11867
diff changeset
    11
# any later version.
83739be20fab [pyramid] Add a copyright and docstring to all modules
Denis Laxalde <denis.laxalde@logilab.fr>
parents: 11867
diff changeset
    12
#
83739be20fab [pyramid] Add a copyright and docstring to all modules
Denis Laxalde <denis.laxalde@logilab.fr>
parents: 11867
diff changeset
    13
# CubicWeb is distributed in the hope that it will be useful, but WITHOUT
83739be20fab [pyramid] Add a copyright and docstring to all modules
Denis Laxalde <denis.laxalde@logilab.fr>
parents: 11867
diff changeset
    14
# ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
83739be20fab [pyramid] Add a copyright and docstring to all modules
Denis Laxalde <denis.laxalde@logilab.fr>
parents: 11867
diff changeset
    15
# FOR A PARTICULAR PURPOSE.  See the GNU Lesser General Public License for more
83739be20fab [pyramid] Add a copyright and docstring to all modules
Denis Laxalde <denis.laxalde@logilab.fr>
parents: 11867
diff changeset
    16
# details.
83739be20fab [pyramid] Add a copyright and docstring to all modules
Denis Laxalde <denis.laxalde@logilab.fr>
parents: 11867
diff changeset
    17
#
83739be20fab [pyramid] Add a copyright and docstring to all modules
Denis Laxalde <denis.laxalde@logilab.fr>
parents: 11867
diff changeset
    18
# You should have received a copy of the GNU Lesser General Public License along
83739be20fab [pyramid] Add a copyright and docstring to all modules
Denis Laxalde <denis.laxalde@logilab.fr>
parents: 11867
diff changeset
    19
# with CubicWeb.  If not, see <http://www.gnu.org/licenses/>.
83739be20fab [pyramid] Add a copyright and docstring to all modules
Denis Laxalde <denis.laxalde@logilab.fr>
parents: 11867
diff changeset
    20
11637
a9cde6a3394c Implements auto-reload and daemon mode.
Christophe de Vienne <christophe@unlish.com>
parents: 11633
diff changeset
    21
"""
a9cde6a3394c Implements auto-reload and daemon mode.
Christophe de Vienne <christophe@unlish.com>
parents: 11633
diff changeset
    22
Provides a 'pyramid' command as a replacement to the 'start' command.
a9cde6a3394c Implements auto-reload and daemon mode.
Christophe de Vienne <christophe@unlish.com>
parents: 11633
diff changeset
    23
a9cde6a3394c Implements auto-reload and daemon mode.
Christophe de Vienne <christophe@unlish.com>
parents: 11633
diff changeset
    24
The reloading strategy is heavily inspired by (and partially copied from)
a9cde6a3394c Implements auto-reload and daemon mode.
Christophe de Vienne <christophe@unlish.com>
parents: 11633
diff changeset
    25
the pyramid script 'pserve'.
a9cde6a3394c Implements auto-reload and daemon mode.
Christophe de Vienne <christophe@unlish.com>
parents: 11633
diff changeset
    26
"""
11967
83739be20fab [pyramid] Add a copyright and docstring to all modules
Denis Laxalde <denis.laxalde@logilab.fr>
parents: 11867
diff changeset
    27
11637
a9cde6a3394c Implements auto-reload and daemon mode.
Christophe de Vienne <christophe@unlish.com>
parents: 11633
diff changeset
    28
import os
a9cde6a3394c Implements auto-reload and daemon mode.
Christophe de Vienne <christophe@unlish.com>
parents: 11633
diff changeset
    29
import signal
a9cde6a3394c Implements auto-reload and daemon mode.
Christophe de Vienne <christophe@unlish.com>
parents: 11633
diff changeset
    30
import sys
a9cde6a3394c Implements auto-reload and daemon mode.
Christophe de Vienne <christophe@unlish.com>
parents: 11633
diff changeset
    31
import time
a9cde6a3394c Implements auto-reload and daemon mode.
Christophe de Vienne <christophe@unlish.com>
parents: 11633
diff changeset
    32
import threading
a9cde6a3394c Implements auto-reload and daemon mode.
Christophe de Vienne <christophe@unlish.com>
parents: 11633
diff changeset
    33
import subprocess
a9cde6a3394c Implements auto-reload and daemon mode.
Christophe de Vienne <christophe@unlish.com>
parents: 11633
diff changeset
    34
12736
5add82b08a6d [cubicweb-ctl] backport --loglevel option of pyramid to all instance commands
Laurent Peuch <cortex@worlddomination.be>
parents: 12730
diff changeset
    35
from logilab.common.configuration import merge_options
5add82b08a6d [cubicweb-ctl] backport --loglevel option of pyramid to all instance commands
Laurent Peuch <cortex@worlddomination.be>
parents: 12730
diff changeset
    36
11633
ffe4040cf4a2 Implements the 'pyramid' command.
Christophe de Vienne <christophe@unlish.com>
parents:
diff changeset
    37
from cubicweb.cwctl import CWCTL, InstanceCommand, init_cmdline_log_threshold
11681
b23d58050076 Merge cubicweb-pyramid cube
Yann Voté <yann.vote@logilab.fr>
parents: 11680
diff changeset
    38
from cubicweb.pyramid import wsgi_application_from_cwconfig
12588
fa292e905edc [pyramid/enh] generate pyramid.ini "create" and on "pyramid" command if needed
Laurent Peuch <cortex@worlddomination.be>
parents: 12567
diff changeset
    39
from cubicweb.pyramid.config import get_random_secret_key
12780
8caa109dfe94 [debug] add in each html snippet from where it has been generated in the code
Laurent Peuch <cortex@worlddomination.be>
parents: 12751
diff changeset
    40
from cubicweb.view import inject_html_generating_call_on_w
12737
56f7386bc6b9 [cubicweb-ctl] backport --dbglevel option of pyramid to all instance commands
Laurent Peuch <cortex@worlddomination.be>
parents: 12736
diff changeset
    41
from cubicweb.server import serverctl
12053
c3c9f2e1424c [pyramid] Add a "pyramid" instance configuration type
Denis Laxalde <denis.laxalde@logilab.fr>
parents: 12003
diff changeset
    42
from cubicweb.web.webctl import WebCreateHandler
12588
fa292e905edc [pyramid/enh] generate pyramid.ini "create" and on "pyramid" command if needed
Laurent Peuch <cortex@worlddomination.be>
parents: 12567
diff changeset
    43
from cubicweb.toolsutils import fill_templated_file
11633
ffe4040cf4a2 Implements the 'pyramid' command.
Christophe de Vienne <christophe@unlish.com>
parents:
diff changeset
    44
11637
a9cde6a3394c Implements auto-reload and daemon mode.
Christophe de Vienne <christophe@unlish.com>
parents: 11633
diff changeset
    45
import waitress
a9cde6a3394c Implements auto-reload and daemon mode.
Christophe de Vienne <christophe@unlish.com>
parents: 11633
diff changeset
    46
a9cde6a3394c Implements auto-reload and daemon mode.
Christophe de Vienne <christophe@unlish.com>
parents: 11633
diff changeset
    47
MAXFD = 1024
a9cde6a3394c Implements auto-reload and daemon mode.
Christophe de Vienne <christophe@unlish.com>
parents: 11633
diff changeset
    48
11680
e1caf133b81c [ccplugin] flake8
Arthur Lutz <arthur.lutz@logilab.fr>
parents: 11679
diff changeset
    49
12588
fa292e905edc [pyramid/enh] generate pyramid.ini "create" and on "pyramid" command if needed
Laurent Peuch <cortex@worlddomination.be>
parents: 12567
diff changeset
    50
def _generate_pyramid_ini_file(pyramid_ini_path):
12602
2beda828c1bf [pyramid/doc] bad docstring
Laurent Peuch <cortex@worlddomination.be>
parents: 12601
diff changeset
    51
    """Write a 'pyramid.ini' file into apphome."""
12588
fa292e905edc [pyramid/enh] generate pyramid.ini "create" and on "pyramid" command if needed
Laurent Peuch <cortex@worlddomination.be>
parents: 12567
diff changeset
    52
    template_fpath = os.path.join(os.path.dirname(__file__), 'pyramid.ini.tmpl')
fa292e905edc [pyramid/enh] generate pyramid.ini "create" and on "pyramid" command if needed
Laurent Peuch <cortex@worlddomination.be>
parents: 12567
diff changeset
    53
    context = {
fa292e905edc [pyramid/enh] generate pyramid.ini "create" and on "pyramid" command if needed
Laurent Peuch <cortex@worlddomination.be>
parents: 12567
diff changeset
    54
        'secret_1': get_random_secret_key(),
fa292e905edc [pyramid/enh] generate pyramid.ini "create" and on "pyramid" command if needed
Laurent Peuch <cortex@worlddomination.be>
parents: 12567
diff changeset
    55
        'secret_2': get_random_secret_key(),
fa292e905edc [pyramid/enh] generate pyramid.ini "create" and on "pyramid" command if needed
Laurent Peuch <cortex@worlddomination.be>
parents: 12567
diff changeset
    56
        'secret_3': get_random_secret_key(),
fa292e905edc [pyramid/enh] generate pyramid.ini "create" and on "pyramid" command if needed
Laurent Peuch <cortex@worlddomination.be>
parents: 12567
diff changeset
    57
    }
12601
f28a19408d3d [pyramid/misc] remove useless variable
Laurent Peuch <cortex@worlddomination.be>
parents: 12590
diff changeset
    58
    fill_templated_file(template_fpath, pyramid_ini_path, context)
12588
fa292e905edc [pyramid/enh] generate pyramid.ini "create" and on "pyramid" command if needed
Laurent Peuch <cortex@worlddomination.be>
parents: 12567
diff changeset
    59
fa292e905edc [pyramid/enh] generate pyramid.ini "create" and on "pyramid" command if needed
Laurent Peuch <cortex@worlddomination.be>
parents: 12567
diff changeset
    60
12053
c3c9f2e1424c [pyramid] Add a "pyramid" instance configuration type
Denis Laxalde <denis.laxalde@logilab.fr>
parents: 12003
diff changeset
    61
class PyramidCreateHandler(serverctl.RepositoryCreateHandler,
c3c9f2e1424c [pyramid] Add a "pyramid" instance configuration type
Denis Laxalde <denis.laxalde@logilab.fr>
parents: 12003
diff changeset
    62
                           WebCreateHandler):
c3c9f2e1424c [pyramid] Add a "pyramid" instance configuration type
Denis Laxalde <denis.laxalde@logilab.fr>
parents: 12003
diff changeset
    63
    cfgname = 'pyramid'
c3c9f2e1424c [pyramid] Add a "pyramid" instance configuration type
Denis Laxalde <denis.laxalde@logilab.fr>
parents: 12003
diff changeset
    64
c3c9f2e1424c [pyramid] Add a "pyramid" instance configuration type
Denis Laxalde <denis.laxalde@logilab.fr>
parents: 12003
diff changeset
    65
    def bootstrap(self, cubes, automatic=False, inputlevel=0):
c3c9f2e1424c [pyramid] Add a "pyramid" instance configuration type
Denis Laxalde <denis.laxalde@logilab.fr>
parents: 12003
diff changeset
    66
        serverctl.RepositoryCreateHandler.bootstrap(self, cubes, automatic, inputlevel)
c3c9f2e1424c [pyramid] Add a "pyramid" instance configuration type
Denis Laxalde <denis.laxalde@logilab.fr>
parents: 12003
diff changeset
    67
        # Call WebCreateHandler.bootstrap to prompt about get anonymous-user.
c3c9f2e1424c [pyramid] Add a "pyramid" instance configuration type
Denis Laxalde <denis.laxalde@logilab.fr>
parents: 12003
diff changeset
    68
        WebCreateHandler.bootstrap(self, cubes, automatic, inputlevel)
c3c9f2e1424c [pyramid] Add a "pyramid" instance configuration type
Denis Laxalde <denis.laxalde@logilab.fr>
parents: 12003
diff changeset
    69
        self.config.write_development_ini(cubes)
c3c9f2e1424c [pyramid] Add a "pyramid" instance configuration type
Denis Laxalde <denis.laxalde@logilab.fr>
parents: 12003
diff changeset
    70
c3c9f2e1424c [pyramid] Add a "pyramid" instance configuration type
Denis Laxalde <denis.laxalde@logilab.fr>
parents: 12003
diff changeset
    71
12530
9d88e1177c35 Remove Twisted web server
Denis Laxalde <denis.laxalde@logilab.fr>
parents: 12216
diff changeset
    72
class AllInOneCreateHandler(serverctl.RepositoryCreateHandler,
9d88e1177c35 Remove Twisted web server
Denis Laxalde <denis.laxalde@logilab.fr>
parents: 12216
diff changeset
    73
                            WebCreateHandler):
9d88e1177c35 Remove Twisted web server
Denis Laxalde <denis.laxalde@logilab.fr>
parents: 12216
diff changeset
    74
    """configuration to get an instance running in a Pyramid web server
9d88e1177c35 Remove Twisted web server
Denis Laxalde <denis.laxalde@logilab.fr>
parents: 12216
diff changeset
    75
    integrating a repository server in the same process
9d88e1177c35 Remove Twisted web server
Denis Laxalde <denis.laxalde@logilab.fr>
parents: 12216
diff changeset
    76
    """
9d88e1177c35 Remove Twisted web server
Denis Laxalde <denis.laxalde@logilab.fr>
parents: 12216
diff changeset
    77
    cfgname = 'all-in-one'
9d88e1177c35 Remove Twisted web server
Denis Laxalde <denis.laxalde@logilab.fr>
parents: 12216
diff changeset
    78
9d88e1177c35 Remove Twisted web server
Denis Laxalde <denis.laxalde@logilab.fr>
parents: 12216
diff changeset
    79
    def bootstrap(self, cubes, automatic=False, inputlevel=0):
9d88e1177c35 Remove Twisted web server
Denis Laxalde <denis.laxalde@logilab.fr>
parents: 12216
diff changeset
    80
        """bootstrap this configuration"""
9d88e1177c35 Remove Twisted web server
Denis Laxalde <denis.laxalde@logilab.fr>
parents: 12216
diff changeset
    81
        serverctl.RepositoryCreateHandler.bootstrap(self, cubes, automatic, inputlevel)
9d88e1177c35 Remove Twisted web server
Denis Laxalde <denis.laxalde@logilab.fr>
parents: 12216
diff changeset
    82
        WebCreateHandler.bootstrap(self, cubes, automatic, inputlevel)
12588
fa292e905edc [pyramid/enh] generate pyramid.ini "create" and on "pyramid" command if needed
Laurent Peuch <cortex@worlddomination.be>
parents: 12567
diff changeset
    83
        _generate_pyramid_ini_file(os.path.join(self.config.apphome, "pyramid.ini"))
12530
9d88e1177c35 Remove Twisted web server
Denis Laxalde <denis.laxalde@logilab.fr>
parents: 12216
diff changeset
    84
9d88e1177c35 Remove Twisted web server
Denis Laxalde <denis.laxalde@logilab.fr>
parents: 12216
diff changeset
    85
11633
ffe4040cf4a2 Implements the 'pyramid' command.
Christophe de Vienne <christophe@unlish.com>
parents:
diff changeset
    86
class PyramidStartHandler(InstanceCommand):
ffe4040cf4a2 Implements the 'pyramid' command.
Christophe de Vienne <christophe@unlish.com>
parents:
diff changeset
    87
    """Start an interactive pyramid server.
ffe4040cf4a2 Implements the 'pyramid' command.
Christophe de Vienne <christophe@unlish.com>
parents:
diff changeset
    88
ffe4040cf4a2 Implements the 'pyramid' command.
Christophe de Vienne <christophe@unlish.com>
parents:
diff changeset
    89
    <instance>
ffe4040cf4a2 Implements the 'pyramid' command.
Christophe de Vienne <christophe@unlish.com>
parents:
diff changeset
    90
      identifier of the instance to configure.
ffe4040cf4a2 Implements the 'pyramid' command.
Christophe de Vienne <christophe@unlish.com>
parents:
diff changeset
    91
    """
ffe4040cf4a2 Implements the 'pyramid' command.
Christophe de Vienne <christophe@unlish.com>
parents:
diff changeset
    92
    name = 'pyramid'
11814
ab8f652a9c99 [pyramid] Add action verb used in some messages displayed by the command
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 11813
diff changeset
    93
    actionverb = 'started'
11633
ffe4040cf4a2 Implements the 'pyramid' command.
Christophe de Vienne <christophe@unlish.com>
parents:
diff changeset
    94
12736
5add82b08a6d [cubicweb-ctl] backport --loglevel option of pyramid to all instance commands
Laurent Peuch <cortex@worlddomination.be>
parents: 12730
diff changeset
    95
    options = merge_options((
11645
2a949974002d --debug now activates all debug options
Christophe de Vienne <christophe@unlish.com>
parents: 11644
diff changeset
    96
        ('debug-mode',
2a949974002d --debug now activates all debug options
Christophe de Vienne <christophe@unlish.com>
parents: 11644
diff changeset
    97
         {'action': 'store_true',
2a949974002d --debug now activates all debug options
Christophe de Vienne <christophe@unlish.com>
parents: 11644
diff changeset
    98
          'help': 'Activate the repository debug mode ('
12730
6c48a49cd3c2 [pyramid/ctl] pyramid command will always run in foreground from now on
Laurent Peuch <cortex@worlddomination.be>
parents: 12729
diff changeset
    99
                  'logs in the console and the debug toolbar).'}),
11641
3d4e7be2e3c3 Add a --no-daemon option
Christophe de Vienne <christophe@unlish.com>
parents: 11640
diff changeset
   100
        ('debug',
11633
ffe4040cf4a2 Implements the 'pyramid' command.
Christophe de Vienne <christophe@unlish.com>
parents:
diff changeset
   101
         {'short': 'D', 'action': 'store_true',
12730
6c48a49cd3c2 [pyramid/ctl] pyramid command will always run in foreground from now on
Laurent Peuch <cortex@worlddomination.be>
parents: 12729
diff changeset
   102
          'help': 'Equals to "--debug-mode --reload"'}),
12751
30b205676182 [pyramid/ctl] add a new option to activate the debugtoolbar (-t)
Laurent Peuch <cortex@worlddomination.be>
parents: 12737
diff changeset
   103
        ('toolbar',
30b205676182 [pyramid/ctl] add a new option to activate the debugtoolbar (-t)
Laurent Peuch <cortex@worlddomination.be>
parents: 12737
diff changeset
   104
         {'short': 't', 'action': 'store_true',
30b205676182 [pyramid/ctl] add a new option to activate the debugtoolbar (-t)
Laurent Peuch <cortex@worlddomination.be>
parents: 12737
diff changeset
   105
          'help': 'Activate the pyramid debug toolbar'
30b205676182 [pyramid/ctl] add a new option to activate the debugtoolbar (-t)
Laurent Peuch <cortex@worlddomination.be>
parents: 12737
diff changeset
   106
                  '(the pypi "pyramid_debugtoolbar" package must be installed)'}),
11637
a9cde6a3394c Implements auto-reload and daemon mode.
Christophe de Vienne <christophe@unlish.com>
parents: 11633
diff changeset
   107
        ('reload',
a9cde6a3394c Implements auto-reload and daemon mode.
Christophe de Vienne <christophe@unlish.com>
parents: 11633
diff changeset
   108
         {'action': 'store_true',
a9cde6a3394c Implements auto-reload and daemon mode.
Christophe de Vienne <christophe@unlish.com>
parents: 11633
diff changeset
   109
          'help': 'Restart the server if any source file is changed'}),
a9cde6a3394c Implements auto-reload and daemon mode.
Christophe de Vienne <christophe@unlish.com>
parents: 11633
diff changeset
   110
        ('reload-interval',
a9cde6a3394c Implements auto-reload and daemon mode.
Christophe de Vienne <christophe@unlish.com>
parents: 11633
diff changeset
   111
         {'type': 'int', 'default': 1,
a9cde6a3394c Implements auto-reload and daemon mode.
Christophe de Vienne <christophe@unlish.com>
parents: 11633
diff changeset
   112
          'help': 'Interval, in seconds, between file modifications checks'}),
11648
9a112017974a Add profiling options
Christophe de Vienne <christophe@unlish.com>
parents: 11647
diff changeset
   113
        ('profile',
11652
e95725d7ce90 Allow to override config file options by cmdline arguments (closes #5724484)
David Douard <david.douard@logilab.fr>
parents: 11648
diff changeset
   114
         {'action': 'store_true',
11648
9a112017974a Add profiling options
Christophe de Vienne <christophe@unlish.com>
parents: 11647
diff changeset
   115
          'default': False,
9a112017974a Add profiling options
Christophe de Vienne <christophe@unlish.com>
parents: 11647
diff changeset
   116
          'help': 'Enable profiling'}),
9a112017974a Add profiling options
Christophe de Vienne <christophe@unlish.com>
parents: 11647
diff changeset
   117
        ('profile-output',
9a112017974a Add profiling options
Christophe de Vienne <christophe@unlish.com>
parents: 11647
diff changeset
   118
         {'type': 'string',
9a112017974a Add profiling options
Christophe de Vienne <christophe@unlish.com>
parents: 11647
diff changeset
   119
          'default': None,
9a112017974a Add profiling options
Christophe de Vienne <christophe@unlish.com>
parents: 11647
diff changeset
   120
          'help': 'Profiling output file (default: "program.prof")'}),
9a112017974a Add profiling options
Christophe de Vienne <christophe@unlish.com>
parents: 11647
diff changeset
   121
        ('profile-dump-every',
9a112017974a Add profiling options
Christophe de Vienne <christophe@unlish.com>
parents: 11647
diff changeset
   122
         {'type': 'int',
9a112017974a Add profiling options
Christophe de Vienne <christophe@unlish.com>
parents: 11647
diff changeset
   123
          'default': None,
9a112017974a Add profiling options
Christophe de Vienne <christophe@unlish.com>
parents: 11647
diff changeset
   124
          'metavar': 'N',
9a112017974a Add profiling options
Christophe de Vienne <christophe@unlish.com>
parents: 11647
diff changeset
   125
          'help': 'Dump profile stats to ouput every N requests '
9a112017974a Add profiling options
Christophe de Vienne <christophe@unlish.com>
parents: 11647
diff changeset
   126
                  '(default: 100)'}),
11813
8a04a2cb5ba4 [pyramid] No more need to check CW version since it's now shipped with it
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 11681
diff changeset
   127
        ('param',
8a04a2cb5ba4 [pyramid] No more need to check CW version since it's now shipped with it
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 11681
diff changeset
   128
         {'short': 'p',
8a04a2cb5ba4 [pyramid] No more need to check CW version since it's now shipped with it
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 11681
diff changeset
   129
          'type': 'named',
8a04a2cb5ba4 [pyramid] No more need to check CW version since it's now shipped with it
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 11681
diff changeset
   130
          'metavar': 'key1:value1,key2:value2',
8a04a2cb5ba4 [pyramid] No more need to check CW version since it's now shipped with it
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 11681
diff changeset
   131
          'default': {},
8a04a2cb5ba4 [pyramid] No more need to check CW version since it's now shipped with it
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 11681
diff changeset
   132
          'help': 'override <key> configuration file option with <value>.'}),
12736
5add82b08a6d [cubicweb-ctl] backport --loglevel option of pyramid to all instance commands
Laurent Peuch <cortex@worlddomination.be>
parents: 12730
diff changeset
   133
    ) + InstanceCommand.options)
11633
ffe4040cf4a2 Implements the 'pyramid' command.
Christophe de Vienne <christophe@unlish.com>
parents:
diff changeset
   134
11637
a9cde6a3394c Implements auto-reload and daemon mode.
Christophe de Vienne <christophe@unlish.com>
parents: 11633
diff changeset
   135
    _reloader_environ_key = 'CW_RELOADER_SHOULD_RUN'
a9cde6a3394c Implements auto-reload and daemon mode.
Christophe de Vienne <christophe@unlish.com>
parents: 11633
diff changeset
   136
a9cde6a3394c Implements auto-reload and daemon mode.
Christophe de Vienne <christophe@unlish.com>
parents: 11633
diff changeset
   137
    def debug(self, msg):
a9cde6a3394c Implements auto-reload and daemon mode.
Christophe de Vienne <christophe@unlish.com>
parents: 11633
diff changeset
   138
        print('DEBUG - %s' % msg)
a9cde6a3394c Implements auto-reload and daemon mode.
Christophe de Vienne <christophe@unlish.com>
parents: 11633
diff changeset
   139
a9cde6a3394c Implements auto-reload and daemon mode.
Christophe de Vienne <christophe@unlish.com>
parents: 11633
diff changeset
   140
    def info(self, msg):
a9cde6a3394c Implements auto-reload and daemon mode.
Christophe de Vienne <christophe@unlish.com>
parents: 11633
diff changeset
   141
        print('INFO - %s' % msg)
a9cde6a3394c Implements auto-reload and daemon mode.
Christophe de Vienne <christophe@unlish.com>
parents: 11633
diff changeset
   142
a9cde6a3394c Implements auto-reload and daemon mode.
Christophe de Vienne <christophe@unlish.com>
parents: 11633
diff changeset
   143
    def quote_first_command_arg(self, arg):
a9cde6a3394c Implements auto-reload and daemon mode.
Christophe de Vienne <christophe@unlish.com>
parents: 11633
diff changeset
   144
        """
a9cde6a3394c Implements auto-reload and daemon mode.
Christophe de Vienne <christophe@unlish.com>
parents: 11633
diff changeset
   145
        There's a bug in Windows when running an executable that's
a9cde6a3394c Implements auto-reload and daemon mode.
Christophe de Vienne <christophe@unlish.com>
parents: 11633
diff changeset
   146
        located inside a path with a space in it.  This method handles
a9cde6a3394c Implements auto-reload and daemon mode.
Christophe de Vienne <christophe@unlish.com>
parents: 11633
diff changeset
   147
        that case, or on non-Windows systems or an executable with no
a9cde6a3394c Implements auto-reload and daemon mode.
Christophe de Vienne <christophe@unlish.com>
parents: 11633
diff changeset
   148
        spaces, it just leaves well enough alone.
a9cde6a3394c Implements auto-reload and daemon mode.
Christophe de Vienne <christophe@unlish.com>
parents: 11633
diff changeset
   149
        """
a9cde6a3394c Implements auto-reload and daemon mode.
Christophe de Vienne <christophe@unlish.com>
parents: 11633
diff changeset
   150
        if (sys.platform != 'win32' or ' ' not in arg):
a9cde6a3394c Implements auto-reload and daemon mode.
Christophe de Vienne <christophe@unlish.com>
parents: 11633
diff changeset
   151
            # Problem does not apply:
a9cde6a3394c Implements auto-reload and daemon mode.
Christophe de Vienne <christophe@unlish.com>
parents: 11633
diff changeset
   152
            return arg
a9cde6a3394c Implements auto-reload and daemon mode.
Christophe de Vienne <christophe@unlish.com>
parents: 11633
diff changeset
   153
        try:
a9cde6a3394c Implements auto-reload and daemon mode.
Christophe de Vienne <christophe@unlish.com>
parents: 11633
diff changeset
   154
            import win32api
a9cde6a3394c Implements auto-reload and daemon mode.
Christophe de Vienne <christophe@unlish.com>
parents: 11633
diff changeset
   155
        except ImportError:
a9cde6a3394c Implements auto-reload and daemon mode.
Christophe de Vienne <christophe@unlish.com>
parents: 11633
diff changeset
   156
            raise ValueError(
a9cde6a3394c Implements auto-reload and daemon mode.
Christophe de Vienne <christophe@unlish.com>
parents: 11633
diff changeset
   157
                "The executable %r contains a space, and in order to "
a9cde6a3394c Implements auto-reload and daemon mode.
Christophe de Vienne <christophe@unlish.com>
parents: 11633
diff changeset
   158
                "handle this issue you must have the win32api module "
a9cde6a3394c Implements auto-reload and daemon mode.
Christophe de Vienne <christophe@unlish.com>
parents: 11633
diff changeset
   159
                "installed" % arg)
a9cde6a3394c Implements auto-reload and daemon mode.
Christophe de Vienne <christophe@unlish.com>
parents: 11633
diff changeset
   160
        arg = win32api.GetShortPathName(arg)
a9cde6a3394c Implements auto-reload and daemon mode.
Christophe de Vienne <christophe@unlish.com>
parents: 11633
diff changeset
   161
        return arg
a9cde6a3394c Implements auto-reload and daemon mode.
Christophe de Vienne <christophe@unlish.com>
parents: 11633
diff changeset
   162
11817
48f6ebd33cb9 [pyramid] Install file listing monitored files in application home
Denis Laxalde <denis.laxalde@logilab.fr>
parents: 11814
diff changeset
   163
    def restart_with_reloader(self, filelist_path):
11637
a9cde6a3394c Implements auto-reload and daemon mode.
Christophe de Vienne <christophe@unlish.com>
parents: 11633
diff changeset
   164
        self.debug('Starting subprocess with file monitor')
a9cde6a3394c Implements auto-reload and daemon mode.
Christophe de Vienne <christophe@unlish.com>
parents: 11633
diff changeset
   165
11817
48f6ebd33cb9 [pyramid] Install file listing monitored files in application home
Denis Laxalde <denis.laxalde@logilab.fr>
parents: 11814
diff changeset
   166
        # Create or clear monitored files list file.
48f6ebd33cb9 [pyramid] Install file listing monitored files in application home
Denis Laxalde <denis.laxalde@logilab.fr>
parents: 11814
diff changeset
   167
        with open(filelist_path, 'w') as f:
48f6ebd33cb9 [pyramid] Install file listing monitored files in application home
Denis Laxalde <denis.laxalde@logilab.fr>
parents: 11814
diff changeset
   168
            pass
11638
12de153c0d0e Auto-reload now survives failed reload
Christophe de Vienne <christophe@unlish.com>
parents: 11637
diff changeset
   169
11637
a9cde6a3394c Implements auto-reload and daemon mode.
Christophe de Vienne <christophe@unlish.com>
parents: 11633
diff changeset
   170
        while True:
a9cde6a3394c Implements auto-reload and daemon mode.
Christophe de Vienne <christophe@unlish.com>
parents: 11633
diff changeset
   171
            args = [self.quote_first_command_arg(sys.executable)] + sys.argv
a9cde6a3394c Implements auto-reload and daemon mode.
Christophe de Vienne <christophe@unlish.com>
parents: 11633
diff changeset
   172
            new_environ = os.environ.copy()
a9cde6a3394c Implements auto-reload and daemon mode.
Christophe de Vienne <christophe@unlish.com>
parents: 11633
diff changeset
   173
            new_environ[self._reloader_environ_key] = 'true'
a9cde6a3394c Implements auto-reload and daemon mode.
Christophe de Vienne <christophe@unlish.com>
parents: 11633
diff changeset
   174
            proc = None
a9cde6a3394c Implements auto-reload and daemon mode.
Christophe de Vienne <christophe@unlish.com>
parents: 11633
diff changeset
   175
            try:
a9cde6a3394c Implements auto-reload and daemon mode.
Christophe de Vienne <christophe@unlish.com>
parents: 11633
diff changeset
   176
                try:
a9cde6a3394c Implements auto-reload and daemon mode.
Christophe de Vienne <christophe@unlish.com>
parents: 11633
diff changeset
   177
                    proc = subprocess.Popen(args, env=new_environ)
a9cde6a3394c Implements auto-reload and daemon mode.
Christophe de Vienne <christophe@unlish.com>
parents: 11633
diff changeset
   178
                    exit_code = proc.wait()
a9cde6a3394c Implements auto-reload and daemon mode.
Christophe de Vienne <christophe@unlish.com>
parents: 11633
diff changeset
   179
                    proc = None
11663
6fb9d9276880 [ccplugin] print_function
Julien Cristau <julien.cristau@logilab.fr>
parents: 11658
diff changeset
   180
                    print("Process exited with", exit_code)
11637
a9cde6a3394c Implements auto-reload and daemon mode.
Christophe de Vienne <christophe@unlish.com>
parents: 11633
diff changeset
   181
                except KeyboardInterrupt:
a9cde6a3394c Implements auto-reload and daemon mode.
Christophe de Vienne <christophe@unlish.com>
parents: 11633
diff changeset
   182
                    self.info('^C caught in monitor process')
a9cde6a3394c Implements auto-reload and daemon mode.
Christophe de Vienne <christophe@unlish.com>
parents: 11633
diff changeset
   183
                    return 1
a9cde6a3394c Implements auto-reload and daemon mode.
Christophe de Vienne <christophe@unlish.com>
parents: 11633
diff changeset
   184
            finally:
a9cde6a3394c Implements auto-reload and daemon mode.
Christophe de Vienne <christophe@unlish.com>
parents: 11633
diff changeset
   185
                if proc is not None:
a9cde6a3394c Implements auto-reload and daemon mode.
Christophe de Vienne <christophe@unlish.com>
parents: 11633
diff changeset
   186
                    proc.terminate()
a9cde6a3394c Implements auto-reload and daemon mode.
Christophe de Vienne <christophe@unlish.com>
parents: 11633
diff changeset
   187
                    self.info(
a9cde6a3394c Implements auto-reload and daemon mode.
Christophe de Vienne <christophe@unlish.com>
parents: 11633
diff changeset
   188
                        'Waiting for the server to stop. Hit CTRL-C to exit')
a9cde6a3394c Implements auto-reload and daemon mode.
Christophe de Vienne <christophe@unlish.com>
parents: 11633
diff changeset
   189
                    exit_code = proc.wait()
a9cde6a3394c Implements auto-reload and daemon mode.
Christophe de Vienne <christophe@unlish.com>
parents: 11633
diff changeset
   190
a9cde6a3394c Implements auto-reload and daemon mode.
Christophe de Vienne <christophe@unlish.com>
parents: 11633
diff changeset
   191
            if exit_code != 3:
11638
12de153c0d0e Auto-reload now survives failed reload
Christophe de Vienne <christophe@unlish.com>
parents: 11637
diff changeset
   192
                with open(filelist_path) as f:
12de153c0d0e Auto-reload now survives failed reload
Christophe de Vienne <christophe@unlish.com>
parents: 11637
diff changeset
   193
                    filelist = [line.strip() for line in f]
12de153c0d0e Auto-reload now survives failed reload
Christophe de Vienne <christophe@unlish.com>
parents: 11637
diff changeset
   194
                if filelist:
12de153c0d0e Auto-reload now survives failed reload
Christophe de Vienne <christophe@unlish.com>
parents: 11637
diff changeset
   195
                    self.info("Reloading failed. Waiting for a file to change")
12de153c0d0e Auto-reload now survives failed reload
Christophe de Vienne <christophe@unlish.com>
parents: 11637
diff changeset
   196
                    mon = Monitor(extra_files=filelist, nomodules=True)
12de153c0d0e Auto-reload now survives failed reload
Christophe de Vienne <christophe@unlish.com>
parents: 11637
diff changeset
   197
                    while mon.check_reload():
12de153c0d0e Auto-reload now survives failed reload
Christophe de Vienne <christophe@unlish.com>
parents: 11637
diff changeset
   198
                        time.sleep(1)
12de153c0d0e Auto-reload now survives failed reload
Christophe de Vienne <christophe@unlish.com>
parents: 11637
diff changeset
   199
                else:
12de153c0d0e Auto-reload now survives failed reload
Christophe de Vienne <christophe@unlish.com>
parents: 11637
diff changeset
   200
                    return exit_code
11637
a9cde6a3394c Implements auto-reload and daemon mode.
Christophe de Vienne <christophe@unlish.com>
parents: 11633
diff changeset
   201
a9cde6a3394c Implements auto-reload and daemon mode.
Christophe de Vienne <christophe@unlish.com>
parents: 11633
diff changeset
   202
            self.info('%s %s %s' % ('-' * 20, 'Restarting', '-' * 20))
a9cde6a3394c Implements auto-reload and daemon mode.
Christophe de Vienne <christophe@unlish.com>
parents: 11633
diff changeset
   203
a9cde6a3394c Implements auto-reload and daemon mode.
Christophe de Vienne <christophe@unlish.com>
parents: 11633
diff changeset
   204
    def set_needreload(self):
a9cde6a3394c Implements auto-reload and daemon mode.
Christophe de Vienne <christophe@unlish.com>
parents: 11633
diff changeset
   205
        self._needreload = True
a9cde6a3394c Implements auto-reload and daemon mode.
Christophe de Vienne <christophe@unlish.com>
parents: 11633
diff changeset
   206
11638
12de153c0d0e Auto-reload now survives failed reload
Christophe de Vienne <christophe@unlish.com>
parents: 11637
diff changeset
   207
    def install_reloader(self, poll_interval, extra_files, filelist_path):
11637
a9cde6a3394c Implements auto-reload and daemon mode.
Christophe de Vienne <christophe@unlish.com>
parents: 11633
diff changeset
   208
        mon = Monitor(
a9cde6a3394c Implements auto-reload and daemon mode.
Christophe de Vienne <christophe@unlish.com>
parents: 11633
diff changeset
   209
            poll_interval=poll_interval, extra_files=extra_files,
11638
12de153c0d0e Auto-reload now survives failed reload
Christophe de Vienne <christophe@unlish.com>
parents: 11637
diff changeset
   210
            atexit=self.set_needreload, filelist_path=filelist_path)
11637
a9cde6a3394c Implements auto-reload and daemon mode.
Christophe de Vienne <christophe@unlish.com>
parents: 11633
diff changeset
   211
        mon_thread = threading.Thread(target=mon.periodic_reload)
a9cde6a3394c Implements auto-reload and daemon mode.
Christophe de Vienne <christophe@unlish.com>
parents: 11633
diff changeset
   212
        mon_thread.daemon = True
a9cde6a3394c Implements auto-reload and daemon mode.
Christophe de Vienne <christophe@unlish.com>
parents: 11633
diff changeset
   213
        mon_thread.start()
a9cde6a3394c Implements auto-reload and daemon mode.
Christophe de Vienne <christophe@unlish.com>
parents: 11633
diff changeset
   214
11647
7f2cfe9f79cb Monitor more configuration files
Christophe de Vienne <christophe@unlish.com>
parents: 11645
diff changeset
   215
    def configfiles(self, cwconfig):
11679
04b127f7ba4e [ccplugin] docstring clarification
Arthur Lutz <arthur.lutz@logilab.fr>
parents: 11672
diff changeset
   216
        """Generate instance configuration filenames"""
11647
7f2cfe9f79cb Monitor more configuration files
Christophe de Vienne <christophe@unlish.com>
parents: 11645
diff changeset
   217
        yield cwconfig.main_config_file()
7f2cfe9f79cb Monitor more configuration files
Christophe de Vienne <christophe@unlish.com>
parents: 11645
diff changeset
   218
        for f in (
7f2cfe9f79cb Monitor more configuration files
Christophe de Vienne <christophe@unlish.com>
parents: 11645
diff changeset
   219
                'sources', 'logging.conf', 'pyramid.ini', 'pyramid-debug.ini'):
7f2cfe9f79cb Monitor more configuration files
Christophe de Vienne <christophe@unlish.com>
parents: 11645
diff changeset
   220
            f = os.path.join(cwconfig.apphome, f)
7f2cfe9f79cb Monitor more configuration files
Christophe de Vienne <christophe@unlish.com>
parents: 11645
diff changeset
   221
            if os.path.exists(f):
7f2cfe9f79cb Monitor more configuration files
Christophe de Vienne <christophe@unlish.com>
parents: 11645
diff changeset
   222
                yield f
7f2cfe9f79cb Monitor more configuration files
Christophe de Vienne <christophe@unlish.com>
parents: 11645
diff changeset
   223
11639
f38ec5e29de3 Watch for i18n files changes for auto-reload
Denis Laxalde <denis.laxalde@logilab.fr>
parents: 11638
diff changeset
   224
    def i18nfiles(self, cwconfig):
11647
7f2cfe9f79cb Monitor more configuration files
Christophe de Vienne <christophe@unlish.com>
parents: 11645
diff changeset
   225
        """Generate instance i18n files"""
11639
f38ec5e29de3 Watch for i18n files changes for auto-reload
Denis Laxalde <denis.laxalde@logilab.fr>
parents: 11638
diff changeset
   226
        i18ndir = os.path.join(cwconfig.apphome, 'i18n')
f38ec5e29de3 Watch for i18n files changes for auto-reload
Denis Laxalde <denis.laxalde@logilab.fr>
parents: 11638
diff changeset
   227
        if os.path.exists(i18ndir):
f38ec5e29de3 Watch for i18n files changes for auto-reload
Denis Laxalde <denis.laxalde@logilab.fr>
parents: 11638
diff changeset
   228
            for lang in cwconfig.available_languages():
f38ec5e29de3 Watch for i18n files changes for auto-reload
Denis Laxalde <denis.laxalde@logilab.fr>
parents: 11638
diff changeset
   229
                f = os.path.join(i18ndir, lang, 'LC_MESSAGES', 'cubicweb.mo')
f38ec5e29de3 Watch for i18n files changes for auto-reload
Denis Laxalde <denis.laxalde@logilab.fr>
parents: 11638
diff changeset
   230
                if os.path.exists(f):
f38ec5e29de3 Watch for i18n files changes for auto-reload
Denis Laxalde <denis.laxalde@logilab.fr>
parents: 11638
diff changeset
   231
                    yield f
f38ec5e29de3 Watch for i18n files changes for auto-reload
Denis Laxalde <denis.laxalde@logilab.fr>
parents: 11638
diff changeset
   232
11633
ffe4040cf4a2 Implements the 'pyramid' command.
Christophe de Vienne <christophe@unlish.com>
parents:
diff changeset
   233
    def pyramid_instance(self, appid):
11637
a9cde6a3394c Implements auto-reload and daemon mode.
Christophe de Vienne <christophe@unlish.com>
parents: 11633
diff changeset
   234
        self._needreload = False
a9cde6a3394c Implements auto-reload and daemon mode.
Christophe de Vienne <christophe@unlish.com>
parents: 11633
diff changeset
   235
11645
2a949974002d --debug now activates all debug options
Christophe de Vienne <christophe@unlish.com>
parents: 11644
diff changeset
   236
        autoreload = self['reload'] or self['debug']
2a949974002d --debug now activates all debug options
Christophe de Vienne <christophe@unlish.com>
parents: 11644
diff changeset
   237
12736
5add82b08a6d [cubicweb-ctl] backport --loglevel option of pyramid to all instance commands
Laurent Peuch <cortex@worlddomination.be>
parents: 12730
diff changeset
   238
        cwconfig = self.cwconfig
11817
48f6ebd33cb9 [pyramid] Install file listing monitored files in application home
Denis Laxalde <denis.laxalde@logilab.fr>
parents: 11814
diff changeset
   239
        filelist_path = os.path.join(cwconfig.apphome,
48f6ebd33cb9 [pyramid] Install file listing monitored files in application home
Denis Laxalde <denis.laxalde@logilab.fr>
parents: 11814
diff changeset
   240
                                     '.pyramid-reload-files.list')
48f6ebd33cb9 [pyramid] Install file listing monitored files in application home
Denis Laxalde <denis.laxalde@logilab.fr>
parents: 11814
diff changeset
   241
12588
fa292e905edc [pyramid/enh] generate pyramid.ini "create" and on "pyramid" command if needed
Laurent Peuch <cortex@worlddomination.be>
parents: 12567
diff changeset
   242
        pyramid_ini_path = os.path.join(cwconfig.apphome, "pyramid.ini")
fa292e905edc [pyramid/enh] generate pyramid.ini "create" and on "pyramid" command if needed
Laurent Peuch <cortex@worlddomination.be>
parents: 12567
diff changeset
   243
        if not os.path.exists(pyramid_ini_path):
fa292e905edc [pyramid/enh] generate pyramid.ini "create" and on "pyramid" command if needed
Laurent Peuch <cortex@worlddomination.be>
parents: 12567
diff changeset
   244
            _generate_pyramid_ini_file(pyramid_ini_path)
fa292e905edc [pyramid/enh] generate pyramid.ini "create" and on "pyramid" command if needed
Laurent Peuch <cortex@worlddomination.be>
parents: 12567
diff changeset
   245
11645
2a949974002d --debug now activates all debug options
Christophe de Vienne <christophe@unlish.com>
parents: 11644
diff changeset
   246
        if autoreload and not os.environ.get(self._reloader_environ_key):
11817
48f6ebd33cb9 [pyramid] Install file listing monitored files in application home
Denis Laxalde <denis.laxalde@logilab.fr>
parents: 11814
diff changeset
   247
            return self.restart_with_reloader(filelist_path)
11637
a9cde6a3394c Implements auto-reload and daemon mode.
Christophe de Vienne <christophe@unlish.com>
parents: 11633
diff changeset
   248
11645
2a949974002d --debug now activates all debug options
Christophe de Vienne <christophe@unlish.com>
parents: 11644
diff changeset
   249
        if autoreload:
11637
a9cde6a3394c Implements auto-reload and daemon mode.
Christophe de Vienne <christophe@unlish.com>
parents: 11633
diff changeset
   250
            _turn_sigterm_into_systemexit()
a9cde6a3394c Implements auto-reload and daemon mode.
Christophe de Vienne <christophe@unlish.com>
parents: 11633
diff changeset
   251
            self.debug('Running reloading file monitor')
11647
7f2cfe9f79cb Monitor more configuration files
Christophe de Vienne <christophe@unlish.com>
parents: 11645
diff changeset
   252
            extra_files = [sys.argv[0]]
7f2cfe9f79cb Monitor more configuration files
Christophe de Vienne <christophe@unlish.com>
parents: 11645
diff changeset
   253
            extra_files.extend(self.configfiles(cwconfig))
11639
f38ec5e29de3 Watch for i18n files changes for auto-reload
Denis Laxalde <denis.laxalde@logilab.fr>
parents: 11638
diff changeset
   254
            extra_files.extend(self.i18nfiles(cwconfig))
11638
12de153c0d0e Auto-reload now survives failed reload
Christophe de Vienne <christophe@unlish.com>
parents: 11637
diff changeset
   255
            self.install_reloader(
12de153c0d0e Auto-reload now survives failed reload
Christophe de Vienne <christophe@unlish.com>
parents: 11637
diff changeset
   256
                self['reload-interval'], extra_files,
11817
48f6ebd33cb9 [pyramid] Install file listing monitored files in application home
Denis Laxalde <denis.laxalde@logilab.fr>
parents: 11814
diff changeset
   257
                filelist_path=filelist_path)
11637
a9cde6a3394c Implements auto-reload and daemon mode.
Christophe de Vienne <christophe@unlish.com>
parents: 11633
diff changeset
   258
12737
56f7386bc6b9 [cubicweb-ctl] backport --dbglevel option of pyramid to all instance commands
Laurent Peuch <cortex@worlddomination.be>
parents: 12736
diff changeset
   259
        # if no loglevel is specified and --debug is here, set log level at debug
56f7386bc6b9 [cubicweb-ctl] backport --dbglevel option of pyramid to all instance commands
Laurent Peuch <cortex@worlddomination.be>
parents: 12736
diff changeset
   260
        if self['loglevel'] is None and self['debug']:
56f7386bc6b9 [cubicweb-ctl] backport --dbglevel option of pyramid to all instance commands
Laurent Peuch <cortex@worlddomination.be>
parents: 12736
diff changeset
   261
            init_cmdline_log_threshold(self.cwconfig, 'debug')
11633
ffe4040cf4a2 Implements the 'pyramid' command.
Christophe de Vienne <christophe@unlish.com>
parents:
diff changeset
   262
12751
30b205676182 [pyramid/ctl] add a new option to activate the debugtoolbar (-t)
Laurent Peuch <cortex@worlddomination.be>
parents: 12737
diff changeset
   263
        # if the debugtoolbar is activated, test if it's importable
30b205676182 [pyramid/ctl] add a new option to activate the debugtoolbar (-t)
Laurent Peuch <cortex@worlddomination.be>
parents: 12737
diff changeset
   264
        if self['toolbar']:
30b205676182 [pyramid/ctl] add a new option to activate the debugtoolbar (-t)
Laurent Peuch <cortex@worlddomination.be>
parents: 12737
diff changeset
   265
            try:
30b205676182 [pyramid/ctl] add a new option to activate the debugtoolbar (-t)
Laurent Peuch <cortex@worlddomination.be>
parents: 12737
diff changeset
   266
                import pyramid_debugtoolbar  # noqa
30b205676182 [pyramid/ctl] add a new option to activate the debugtoolbar (-t)
Laurent Peuch <cortex@worlddomination.be>
parents: 12737
diff changeset
   267
            except ImportError:
30b205676182 [pyramid/ctl] add a new option to activate the debugtoolbar (-t)
Laurent Peuch <cortex@worlddomination.be>
parents: 12737
diff changeset
   268
                print("Error: you've tried to activate the pyramid debugtoolbar but it failed to "
30b205676182 [pyramid/ctl] add a new option to activate the debugtoolbar (-t)
Laurent Peuch <cortex@worlddomination.be>
parents: 12737
diff changeset
   269
                      "import, make sure it's correctly installed by doing a "
30b205676182 [pyramid/ctl] add a new option to activate the debugtoolbar (-t)
Laurent Peuch <cortex@worlddomination.be>
parents: 12737
diff changeset
   270
                      "'pip install pyramid_debugtoolbar'.\nYou can find more information on the "
30b205676182 [pyramid/ctl] add a new option to activate the debugtoolbar (-t)
Laurent Peuch <cortex@worlddomination.be>
parents: 12737
diff changeset
   271
                      "official documentation: "
30b205676182 [pyramid/ctl] add a new option to activate the debugtoolbar (-t)
Laurent Peuch <cortex@worlddomination.be>
parents: 12737
diff changeset
   272
                      "https://docs.pylonsproject.org/projects/pyramid_debugtoolbar/en/latest/")
30b205676182 [pyramid/ctl] add a new option to activate the debugtoolbar (-t)
Laurent Peuch <cortex@worlddomination.be>
parents: 12737
diff changeset
   273
                sys.exit(1)
30b205676182 [pyramid/ctl] add a new option to activate the debugtoolbar (-t)
Laurent Peuch <cortex@worlddomination.be>
parents: 12737
diff changeset
   274
12780
8caa109dfe94 [debug] add in each html snippet from where it has been generated in the code
Laurent Peuch <cortex@worlddomination.be>
parents: 12751
diff changeset
   275
        if self['debug']:
8caa109dfe94 [debug] add in each html snippet from where it has been generated in the code
Laurent Peuch <cortex@worlddomination.be>
parents: 12751
diff changeset
   276
            # this is for injecting those into generated html:
8caa109dfe94 [debug] add in each html snippet from where it has been generated in the code
Laurent Peuch <cortex@worlddomination.be>
parents: 12751
diff changeset
   277
            # > cubicweb-generated-by="module.Class" cubicweb-from-source="/path/to/file.py:42"
8caa109dfe94 [debug] add in each html snippet from where it has been generated in the code
Laurent Peuch <cortex@worlddomination.be>
parents: 12751
diff changeset
   278
            inject_html_generating_call_on_w()
8caa109dfe94 [debug] add in each html snippet from where it has been generated in the code
Laurent Peuch <cortex@worlddomination.be>
parents: 12751
diff changeset
   279
11648
9a112017974a Add profiling options
Christophe de Vienne <christophe@unlish.com>
parents: 11647
diff changeset
   280
        app = wsgi_application_from_cwconfig(
9a112017974a Add profiling options
Christophe de Vienne <christophe@unlish.com>
parents: 11647
diff changeset
   281
            cwconfig, profile=self['profile'],
9a112017974a Add profiling options
Christophe de Vienne <christophe@unlish.com>
parents: 11647
diff changeset
   282
            profile_output=self['profile-output'],
12751
30b205676182 [pyramid/ctl] add a new option to activate the debugtoolbar (-t)
Laurent Peuch <cortex@worlddomination.be>
parents: 12737
diff changeset
   283
            profile_dump_every=self['profile-dump-every'],
30b205676182 [pyramid/ctl] add a new option to activate the debugtoolbar (-t)
Laurent Peuch <cortex@worlddomination.be>
parents: 12737
diff changeset
   284
            debugtoolbar=self['toolbar']
11648
9a112017974a Add profiling options
Christophe de Vienne <christophe@unlish.com>
parents: 11647
diff changeset
   285
        )
11640
e45e4999dc98 Use 'wsgicors' for CORS handling.
Christophe de Vienne <christophe@unlish.com>
parents: 11639
diff changeset
   286
11652
e95725d7ce90 Allow to override config file options by cmdline arguments (closes #5724484)
David Douard <david.douard@logilab.fr>
parents: 11648
diff changeset
   287
        host = cwconfig['interface']
e95725d7ce90 Allow to override config file options by cmdline arguments (closes #5724484)
David Douard <david.douard@logilab.fr>
parents: 11648
diff changeset
   288
        port = cwconfig['port'] or 8080
12216
4de5927871f9 [pyramid] set waitress url_scheme to https when base-url scheme is https
Philippe Pepiot <philippe.pepiot@logilab.fr>
parents: 12053
diff changeset
   289
        url_scheme = ('https' if cwconfig['base-url'].startswith('https')
4de5927871f9 [pyramid] set waitress url_scheme to https when base-url scheme is https
Philippe Pepiot <philippe.pepiot@logilab.fr>
parents: 12053
diff changeset
   290
                      else 'http')
11664
7567e99d6ed5 [ccplugin] get the cw repo from the wsgi app
Julien Cristau <julien.cristau@logilab.fr>
parents: 11663
diff changeset
   291
        repo = app.application.registry['cubicweb.repository']
11633
ffe4040cf4a2 Implements the 'pyramid' command.
Christophe de Vienne <christophe@unlish.com>
parents:
diff changeset
   292
        try:
12590
a5d7fcde74c9 DeprecationWarning: In future versions of Waitress clear_untrusted_proxy_headers will be set to True by default. You may opt-out by setting this value to False, or opt-in explicitly by setting this to True.
Laurent Peuch <cortex@worlddomination.be>
parents: 12588
diff changeset
   293
            waitress.serve(app, host=host, port=port, url_scheme=url_scheme,
a5d7fcde74c9 DeprecationWarning: In future versions of Waitress clear_untrusted_proxy_headers will be set to True by default. You may opt-out by setting this value to False, or opt-in explicitly by setting this to True.
Laurent Peuch <cortex@worlddomination.be>
parents: 12588
diff changeset
   294
                           clear_untrusted_proxy_headers=True)
11633
ffe4040cf4a2 Implements the 'pyramid' command.
Christophe de Vienne <christophe@unlish.com>
parents:
diff changeset
   295
        finally:
ffe4040cf4a2 Implements the 'pyramid' command.
Christophe de Vienne <christophe@unlish.com>
parents:
diff changeset
   296
            repo.shutdown()
11637
a9cde6a3394c Implements auto-reload and daemon mode.
Christophe de Vienne <christophe@unlish.com>
parents: 11633
diff changeset
   297
        if self._needreload:
a9cde6a3394c Implements auto-reload and daemon mode.
Christophe de Vienne <christophe@unlish.com>
parents: 11633
diff changeset
   298
            return 3
a9cde6a3394c Implements auto-reload and daemon mode.
Christophe de Vienne <christophe@unlish.com>
parents: 11633
diff changeset
   299
        return 0
11633
ffe4040cf4a2 Implements the 'pyramid' command.
Christophe de Vienne <christophe@unlish.com>
parents:
diff changeset
   300
11821
7534b32c45e3 Fix (new) flake8 errors
Denis Laxalde <denis.laxalde@logilab.fr>
parents: 11817
diff changeset
   301
11633
ffe4040cf4a2 Implements the 'pyramid' command.
Christophe de Vienne <christophe@unlish.com>
parents:
diff changeset
   302
CWCTL.register(PyramidStartHandler)
11637
a9cde6a3394c Implements auto-reload and daemon mode.
Christophe de Vienne <christophe@unlish.com>
parents: 11633
diff changeset
   303
a9cde6a3394c Implements auto-reload and daemon mode.
Christophe de Vienne <christophe@unlish.com>
parents: 11633
diff changeset
   304
a9cde6a3394c Implements auto-reload and daemon mode.
Christophe de Vienne <christophe@unlish.com>
parents: 11633
diff changeset
   305
def _turn_sigterm_into_systemexit():
11680
e1caf133b81c [ccplugin] flake8
Arthur Lutz <arthur.lutz@logilab.fr>
parents: 11679
diff changeset
   306
    """Attempts to turn a SIGTERM exception into a SystemExit exception."""
11637
a9cde6a3394c Implements auto-reload and daemon mode.
Christophe de Vienne <christophe@unlish.com>
parents: 11633
diff changeset
   307
    try:
a9cde6a3394c Implements auto-reload and daemon mode.
Christophe de Vienne <christophe@unlish.com>
parents: 11633
diff changeset
   308
        import signal
a9cde6a3394c Implements auto-reload and daemon mode.
Christophe de Vienne <christophe@unlish.com>
parents: 11633
diff changeset
   309
    except ImportError:
a9cde6a3394c Implements auto-reload and daemon mode.
Christophe de Vienne <christophe@unlish.com>
parents: 11633
diff changeset
   310
        return
a9cde6a3394c Implements auto-reload and daemon mode.
Christophe de Vienne <christophe@unlish.com>
parents: 11633
diff changeset
   311
a9cde6a3394c Implements auto-reload and daemon mode.
Christophe de Vienne <christophe@unlish.com>
parents: 11633
diff changeset
   312
    def handle_term(signo, frame):
a9cde6a3394c Implements auto-reload and daemon mode.
Christophe de Vienne <christophe@unlish.com>
parents: 11633
diff changeset
   313
        raise SystemExit
a9cde6a3394c Implements auto-reload and daemon mode.
Christophe de Vienne <christophe@unlish.com>
parents: 11633
diff changeset
   314
    signal.signal(signal.SIGTERM, handle_term)
a9cde6a3394c Implements auto-reload and daemon mode.
Christophe de Vienne <christophe@unlish.com>
parents: 11633
diff changeset
   315
a9cde6a3394c Implements auto-reload and daemon mode.
Christophe de Vienne <christophe@unlish.com>
parents: 11633
diff changeset
   316
a9cde6a3394c Implements auto-reload and daemon mode.
Christophe de Vienne <christophe@unlish.com>
parents: 11633
diff changeset
   317
class Monitor(object):
11680
e1caf133b81c [ccplugin] flake8
Arthur Lutz <arthur.lutz@logilab.fr>
parents: 11679
diff changeset
   318
    """A file monitor and server stopper.
11637
a9cde6a3394c Implements auto-reload and daemon mode.
Christophe de Vienne <christophe@unlish.com>
parents: 11633
diff changeset
   319
a9cde6a3394c Implements auto-reload and daemon mode.
Christophe de Vienne <christophe@unlish.com>
parents: 11633
diff changeset
   320
    It is a simplified version of pyramid pserve.Monitor, with little changes:
a9cde6a3394c Implements auto-reload and daemon mode.
Christophe de Vienne <christophe@unlish.com>
parents: 11633
diff changeset
   321
11638
12de153c0d0e Auto-reload now survives failed reload
Christophe de Vienne <christophe@unlish.com>
parents: 11637
diff changeset
   322
    -   The constructor takes extra_files, atexit, nomodules and filelist_path
11637
a9cde6a3394c Implements auto-reload and daemon mode.
Christophe de Vienne <christophe@unlish.com>
parents: 11633
diff changeset
   323
    -   The process is stopped by auto-kill with signal SIGTERM
a9cde6a3394c Implements auto-reload and daemon mode.
Christophe de Vienne <christophe@unlish.com>
parents: 11633
diff changeset
   324
    """
11680
e1caf133b81c [ccplugin] flake8
Arthur Lutz <arthur.lutz@logilab.fr>
parents: 11679
diff changeset
   325
11638
12de153c0d0e Auto-reload now survives failed reload
Christophe de Vienne <christophe@unlish.com>
parents: 11637
diff changeset
   326
    def __init__(self, poll_interval=1, extra_files=[], atexit=None,
12de153c0d0e Auto-reload now survives failed reload
Christophe de Vienne <christophe@unlish.com>
parents: 11637
diff changeset
   327
                 nomodules=False, filelist_path=None):
11637
a9cde6a3394c Implements auto-reload and daemon mode.
Christophe de Vienne <christophe@unlish.com>
parents: 11633
diff changeset
   328
        self.module_mtimes = {}
a9cde6a3394c Implements auto-reload and daemon mode.
Christophe de Vienne <christophe@unlish.com>
parents: 11633
diff changeset
   329
        self.keep_running = True
a9cde6a3394c Implements auto-reload and daemon mode.
Christophe de Vienne <christophe@unlish.com>
parents: 11633
diff changeset
   330
        self.poll_interval = poll_interval
a9cde6a3394c Implements auto-reload and daemon mode.
Christophe de Vienne <christophe@unlish.com>
parents: 11633
diff changeset
   331
        self.extra_files = extra_files
a9cde6a3394c Implements auto-reload and daemon mode.
Christophe de Vienne <christophe@unlish.com>
parents: 11633
diff changeset
   332
        self.atexit = atexit
11638
12de153c0d0e Auto-reload now survives failed reload
Christophe de Vienne <christophe@unlish.com>
parents: 11637
diff changeset
   333
        self.nomodules = nomodules
12de153c0d0e Auto-reload now survives failed reload
Christophe de Vienne <christophe@unlish.com>
parents: 11637
diff changeset
   334
        self.filelist_path = filelist_path
11637
a9cde6a3394c Implements auto-reload and daemon mode.
Christophe de Vienne <christophe@unlish.com>
parents: 11633
diff changeset
   335
a9cde6a3394c Implements auto-reload and daemon mode.
Christophe de Vienne <christophe@unlish.com>
parents: 11633
diff changeset
   336
    def _exit(self):
a9cde6a3394c Implements auto-reload and daemon mode.
Christophe de Vienne <christophe@unlish.com>
parents: 11633
diff changeset
   337
        if self.atexit:
a9cde6a3394c Implements auto-reload and daemon mode.
Christophe de Vienne <christophe@unlish.com>
parents: 11633
diff changeset
   338
            self.atexit()
a9cde6a3394c Implements auto-reload and daemon mode.
Christophe de Vienne <christophe@unlish.com>
parents: 11633
diff changeset
   339
        os.kill(os.getpid(), signal.SIGTERM)
a9cde6a3394c Implements auto-reload and daemon mode.
Christophe de Vienne <christophe@unlish.com>
parents: 11633
diff changeset
   340
a9cde6a3394c Implements auto-reload and daemon mode.
Christophe de Vienne <christophe@unlish.com>
parents: 11633
diff changeset
   341
    def periodic_reload(self):
a9cde6a3394c Implements auto-reload and daemon mode.
Christophe de Vienne <christophe@unlish.com>
parents: 11633
diff changeset
   342
        while True:
a9cde6a3394c Implements auto-reload and daemon mode.
Christophe de Vienne <christophe@unlish.com>
parents: 11633
diff changeset
   343
            if not self.check_reload():
a9cde6a3394c Implements auto-reload and daemon mode.
Christophe de Vienne <christophe@unlish.com>
parents: 11633
diff changeset
   344
                self._exit()
a9cde6a3394c Implements auto-reload and daemon mode.
Christophe de Vienne <christophe@unlish.com>
parents: 11633
diff changeset
   345
                break
a9cde6a3394c Implements auto-reload and daemon mode.
Christophe de Vienne <christophe@unlish.com>
parents: 11633
diff changeset
   346
            time.sleep(self.poll_interval)
a9cde6a3394c Implements auto-reload and daemon mode.
Christophe de Vienne <christophe@unlish.com>
parents: 11633
diff changeset
   347
a9cde6a3394c Implements auto-reload and daemon mode.
Christophe de Vienne <christophe@unlish.com>
parents: 11633
diff changeset
   348
    def check_reload(self):
a9cde6a3394c Implements auto-reload and daemon mode.
Christophe de Vienne <christophe@unlish.com>
parents: 11633
diff changeset
   349
        filenames = list(self.extra_files)
a9cde6a3394c Implements auto-reload and daemon mode.
Christophe de Vienne <christophe@unlish.com>
parents: 11633
diff changeset
   350
11638
12de153c0d0e Auto-reload now survives failed reload
Christophe de Vienne <christophe@unlish.com>
parents: 11637
diff changeset
   351
        if not self.nomodules:
12de153c0d0e Auto-reload now survives failed reload
Christophe de Vienne <christophe@unlish.com>
parents: 11637
diff changeset
   352
            for module in list(sys.modules.values()):
12de153c0d0e Auto-reload now survives failed reload
Christophe de Vienne <christophe@unlish.com>
parents: 11637
diff changeset
   353
                try:
12de153c0d0e Auto-reload now survives failed reload
Christophe de Vienne <christophe@unlish.com>
parents: 11637
diff changeset
   354
                    filename = module.__file__
12de153c0d0e Auto-reload now survives failed reload
Christophe de Vienne <christophe@unlish.com>
parents: 11637
diff changeset
   355
                except (AttributeError, ImportError):
12de153c0d0e Auto-reload now survives failed reload
Christophe de Vienne <christophe@unlish.com>
parents: 11637
diff changeset
   356
                    continue
12de153c0d0e Auto-reload now survives failed reload
Christophe de Vienne <christophe@unlish.com>
parents: 11637
diff changeset
   357
                if filename is not None:
12de153c0d0e Auto-reload now survives failed reload
Christophe de Vienne <christophe@unlish.com>
parents: 11637
diff changeset
   358
                    filenames.append(filename)
11637
a9cde6a3394c Implements auto-reload and daemon mode.
Christophe de Vienne <christophe@unlish.com>
parents: 11633
diff changeset
   359
a9cde6a3394c Implements auto-reload and daemon mode.
Christophe de Vienne <christophe@unlish.com>
parents: 11633
diff changeset
   360
        for filename in filenames:
a9cde6a3394c Implements auto-reload and daemon mode.
Christophe de Vienne <christophe@unlish.com>
parents: 11633
diff changeset
   361
            try:
a9cde6a3394c Implements auto-reload and daemon mode.
Christophe de Vienne <christophe@unlish.com>
parents: 11633
diff changeset
   362
                stat = os.stat(filename)
a9cde6a3394c Implements auto-reload and daemon mode.
Christophe de Vienne <christophe@unlish.com>
parents: 11633
diff changeset
   363
                if stat:
a9cde6a3394c Implements auto-reload and daemon mode.
Christophe de Vienne <christophe@unlish.com>
parents: 11633
diff changeset
   364
                    mtime = stat.st_mtime
a9cde6a3394c Implements auto-reload and daemon mode.
Christophe de Vienne <christophe@unlish.com>
parents: 11633
diff changeset
   365
                else:
a9cde6a3394c Implements auto-reload and daemon mode.
Christophe de Vienne <christophe@unlish.com>
parents: 11633
diff changeset
   366
                    mtime = 0
a9cde6a3394c Implements auto-reload and daemon mode.
Christophe de Vienne <christophe@unlish.com>
parents: 11633
diff changeset
   367
            except (OSError, IOError):
a9cde6a3394c Implements auto-reload and daemon mode.
Christophe de Vienne <christophe@unlish.com>
parents: 11633
diff changeset
   368
                continue
a9cde6a3394c Implements auto-reload and daemon mode.
Christophe de Vienne <christophe@unlish.com>
parents: 11633
diff changeset
   369
            if filename.endswith('.pyc') and os.path.exists(filename[:-1]):
a9cde6a3394c Implements auto-reload and daemon mode.
Christophe de Vienne <christophe@unlish.com>
parents: 11633
diff changeset
   370
                mtime = max(os.stat(filename[:-1]).st_mtime, mtime)
11680
e1caf133b81c [ccplugin] flake8
Arthur Lutz <arthur.lutz@logilab.fr>
parents: 11679
diff changeset
   371
            if filename not in self.module_mtimes:
11637
a9cde6a3394c Implements auto-reload and daemon mode.
Christophe de Vienne <christophe@unlish.com>
parents: 11633
diff changeset
   372
                self.module_mtimes[filename] = mtime
a9cde6a3394c Implements auto-reload and daemon mode.
Christophe de Vienne <christophe@unlish.com>
parents: 11633
diff changeset
   373
            elif self.module_mtimes[filename] < mtime:
a9cde6a3394c Implements auto-reload and daemon mode.
Christophe de Vienne <christophe@unlish.com>
parents: 11633
diff changeset
   374
                print('%s changed; reloading...' % filename)
a9cde6a3394c Implements auto-reload and daemon mode.
Christophe de Vienne <christophe@unlish.com>
parents: 11633
diff changeset
   375
                return False
a9cde6a3394c Implements auto-reload and daemon mode.
Christophe de Vienne <christophe@unlish.com>
parents: 11633
diff changeset
   376
11638
12de153c0d0e Auto-reload now survives failed reload
Christophe de Vienne <christophe@unlish.com>
parents: 11637
diff changeset
   377
        if self.filelist_path:
12de153c0d0e Auto-reload now survives failed reload
Christophe de Vienne <christophe@unlish.com>
parents: 11637
diff changeset
   378
            with open(self.filelist_path) as f:
12de153c0d0e Auto-reload now survives failed reload
Christophe de Vienne <christophe@unlish.com>
parents: 11637
diff changeset
   379
                filelist = set((line.strip() for line in f))
12de153c0d0e Auto-reload now survives failed reload
Christophe de Vienne <christophe@unlish.com>
parents: 11637
diff changeset
   380
12de153c0d0e Auto-reload now survives failed reload
Christophe de Vienne <christophe@unlish.com>
parents: 11637
diff changeset
   381
            filelist.update(filenames)
12de153c0d0e Auto-reload now survives failed reload
Christophe de Vienne <christophe@unlish.com>
parents: 11637
diff changeset
   382
12de153c0d0e Auto-reload now survives failed reload
Christophe de Vienne <christophe@unlish.com>
parents: 11637
diff changeset
   383
            with open(self.filelist_path, 'w') as f:
12de153c0d0e Auto-reload now survives failed reload
Christophe de Vienne <christophe@unlish.com>
parents: 11637
diff changeset
   384
                for filename in filelist:
12de153c0d0e Auto-reload now survives failed reload
Christophe de Vienne <christophe@unlish.com>
parents: 11637
diff changeset
   385
                    f.write('%s\n' % filename)
12de153c0d0e Auto-reload now survives failed reload
Christophe de Vienne <christophe@unlish.com>
parents: 11637
diff changeset
   386
11637
a9cde6a3394c Implements auto-reload and daemon mode.
Christophe de Vienne <christophe@unlish.com>
parents: 11633
diff changeset
   387
        return True