Esempio n. 1
0
def devserver(
    reload,
    watchers,
    workers,
    experimental_spa,
    styleguide,
    prefix,
    pretty,
    environment,
    debug_server,
    bind,
):
    "Starts a lightweight web server for development."

    if bind is None:
        bind = "127.0.0.1:8000"

    if ":" in bind:
        host, port = bind.split(":", 1)
        port = int(port)
    else:
        host = bind
        port = None

    import os

    os.environ["SENTRY_ENVIRONMENT"] = environment
    # NODE_ENV *must* use production for any prod-like environment as third party libraries look
    # for this magic constant
    os.environ["NODE_ENV"] = "production" if environment.startswith(
        "prod") else environment

    from django.conf import settings
    from sentry import options
    from sentry.services.http import SentryHTTPServer

    url_prefix = options.get("system.url-prefix", "")
    parsed_url = urlparse(url_prefix)
    # Make sure we're trying to use a port that we can actually bind to
    needs_https = parsed_url.scheme == "https" and (parsed_url.port
                                                    or 443) > 1024
    has_https = False

    if needs_https:
        from subprocess import check_output

        try:
            check_output(["which", "https"])
            has_https = True
        except Exception:
            has_https = False
            from sentry.runner.initializer import show_big_error

            show_big_error([
                "missing `https` on your `$PATH`, but https is needed",
                "`$ brew install mattrobenolt/stuff/https`",
            ])

    uwsgi_overrides = {
        "http-keepalive": True,
        # Make sure we reload really quickly for local dev in case it
        # doesn't want to shut down nicely on it's own, NO MERCY
        "worker-reload-mercy": 2,
        # We need stdin to support pdb in devserver
        "honour-stdin": True,
        # accept ridiculously large files
        "limit-post": 1 << 30,
        # do something with chunked
        "http-chunked-input": True,
        "thunder-lock": False,
        "timeout": 600,
        "harakiri": 600,
    }

    if reload:
        uwsgi_overrides["py-autoreload"] = 1

    daemons = []

    if experimental_spa:
        os.environ["SENTRY_UI_DEV_ONLY"] = "1"
        if not watchers:
            click.secho(
                "Using experimental SPA mode without watchers enabled has no effect",
                err=True,
                fg="yellow",
            )

    # We proxy all requests through webpacks devserver on the configured port.
    # The backend is served on port+1 and is proxied via the webpack
    # configuration.
    if watchers:
        daemons += settings.SENTRY_WATCHERS

        proxy_port = port
        port = port + 1

        uwsgi_overrides["protocol"] = "http"

        os.environ["FORCE_WEBPACK_DEV_SERVER"] = "1"
        os.environ["SENTRY_WEBPACK_PROXY_PORT"] = "%s" % proxy_port
        os.environ["SENTRY_BACKEND_PORT"] = "%s" % port

        # webpack and/or typescript is causing memory issues
        os.environ["NODE_OPTIONS"] = ((os.environ.get("NODE_OPTIONS", "") +
                                       " --max-old-space-size=4096")).lstrip()

        # Replace the webpack watcher with the drop-in webpack-dev-server
        webpack_config = next(w for w in daemons if w[0] == "webpack")[1]
        webpack_config[0] = os.path.join(
            *os.path.split(webpack_config[0])[0:-1] + ("webpack-dev-server", ))

        daemons = [w for w in daemons if w[0] != "webpack"
                   ] + [("webpack", webpack_config)]
    else:
        # If we are the bare http server, use the http option with uwsgi protocol
        # See https://uwsgi-docs.readthedocs.io/en/latest/HTTP.html
        uwsgi_overrides.update({
            # Make sure uWSGI spawns an HTTP server for us as we don't
            # have a proxy/load-balancer in front in dev mode.
            "http": "%s:%s" % (host, port),
            "protocol": "uwsgi",
            # This is needed to prevent https://git.io/fj7Lw
            "uwsgi-socket": None,
        })

    if workers:
        if settings.CELERY_ALWAYS_EAGER:
            raise click.ClickException(
                "Disable CELERY_ALWAYS_EAGER in your settings file to spawn workers."
            )

        daemons += [_get_daemon("worker"), _get_daemon("cron")]

        from sentry import eventstream

        if eventstream.requires_post_process_forwarder():
            daemons += [_get_daemon("post-process-forwarder")]

        if settings.SENTRY_DEV_PROCESS_SUBSCRIPTIONS:
            if not settings.SENTRY_EVENTSTREAM == "sentry.eventstream.kafka.KafkaEventStream":
                raise click.ClickException(
                    "`SENTRY_DEV_PROCESS_SUBSCRIPTIONS` can only be used when "
                    "`SENTRY_EVENTSTREAM=sentry.eventstream.kafka.KafkaEventStream`."
                )
            for name, topic in settings.KAFKA_SUBSCRIPTION_RESULT_TOPICS.items(
            ):
                daemons += [
                    _get_daemon("subscription-consumer",
                                "--topic",
                                topic,
                                suffix=name)
                ]

    if settings.SENTRY_USE_RELAY:
        daemons += [_get_daemon("ingest")]

    if needs_https and has_https:
        https_port = six.text_type(parsed_url.port)
        https_host = parsed_url.hostname

        # Determine a random port for the backend http server
        import socket

        s = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
        s.setsockopt(socket.SOL_SOCKET, socket.SO_REUSEADDR, 1)
        s.bind((host, 0))
        port = s.getsockname()[1]
        s.close()
        bind = "%s:%d" % (host, port)

        daemons += [("https", [
            "https", "-host", https_host, "-listen", host + ":" + https_port,
            bind
        ])]

    from sentry.runner.commands.devservices import _prepare_containers

    for name, container_options in _prepare_containers("sentry",
                                                       silent=True).items():
        if container_options.get("with_devserver", False):
            daemons += [(name,
                         ["sentry", "devservices", "attach", "--fast", name])]

    # A better log-format for local dev when running through honcho,
    # but if there aren't any other daemons, we don't want to override.
    if daemons:
        uwsgi_overrides[
            "log-format"] = "%(method) %(status) %(uri) %(proto) %(size)"
    else:
        uwsgi_overrides[
            "log-format"] = "[%(ltime)] %(method) %(status) %(uri) %(proto) %(size)"

    server = SentryHTTPServer(host=host,
                              port=port,
                              workers=1,
                              extra_options=uwsgi_overrides,
                              debug=debug_server)

    # If we don't need any other daemons, just launch a normal uwsgi webserver
    # and avoid dealing with subprocesses
    if not daemons:
        return server.run()

    import sys
    from subprocess import list2cmdline
    from honcho.manager import Manager
    from honcho.printer import Printer

    os.environ["PYTHONUNBUFFERED"] = "true"

    if debug_server:
        threading.Thread(target=server.run).start()
    else:
        # Make sure that the environment is prepared before honcho takes over
        # This sets all the appropriate uwsgi env vars, etc
        server.prepare_environment()
        daemons += [_get_daemon("server")]

    if styleguide:
        daemons += [_get_daemon("storybook")]

    cwd = os.path.realpath(
        os.path.join(settings.PROJECT_ROOT, os.pardir, os.pardir))

    honcho_printer = Printer(prefix=prefix)

    if pretty:
        from sentry.runner.formatting import monkeypatch_honcho_write

        honcho_printer.write = types.MethodType(monkeypatch_honcho_write,
                                                honcho_printer)

    manager = Manager(honcho_printer)
    for name, cmd in daemons:
        manager.add_process(name, list2cmdline(cmd), quiet=False, cwd=cwd)

    manager.loop()
    sys.exit(manager.returncode)
Esempio n. 2
0
def devserver(reload, watchers, workers, browser_reload, environment, bind):
    "Starts a lightweight web server for development."
    if ':' in bind:
        host, port = bind.split(':', 1)
        port = int(port)
    else:
        host = bind
        port = None

    import os

    os.environ['SENTRY_ENVIRONMENT'] = environment

    from django.conf import settings
    from sentry import options
    from sentry.services.http import SentryHTTPServer

    url_prefix = options.get('system.url-prefix', '')
    needs_https = url_prefix.startswith('https://')
    has_https = False

    if needs_https:
        from subprocess import check_output
        try:
            check_output(['which', 'https'])
            has_https = True
        except Exception:
            has_https = False
            from sentry.runner.initializer import show_big_error
            show_big_error([
                'missing `https` on your `$PATH`, but https is needed',
                '`$ brew install mattrobenolt/stuff/https`',
            ])

    uwsgi_overrides = {
        # Make sure we don't try and use uwsgi protocol
        'protocol': 'http',
        # Make sure we reload really quickly for local dev in case it
        # doesn't want to shut down nicely on it's own, NO MERCY
        'worker-reload-mercy': 2,
        # We need stdin to support pdb in devserver
        'honour-stdin': True,
    }

    if reload:
        uwsgi_overrides['py-autoreload'] = 1

    daemons = []

    if watchers:
        daemons += settings.SENTRY_WATCHERS

    if workers:
        if settings.CELERY_ALWAYS_EAGER:
            raise click.ClickException('Disable CELERY_ALWAYS_EAGER in your settings file to spawn workers.')

        daemons += [
            ('worker', ['sentry', 'run', 'worker', '-c', '1', '--autoreload']),
            ('cron', ['sentry', 'run', 'cron', '--autoreload']),
        ]

    if needs_https and has_https:
        from six.moves.urllib.parse import urlparse
        parsed_url = urlparse(url_prefix)
        https_port = six.text_type(parsed_url.port or 443)
        https_host = parsed_url.hostname

        # Determine a random port for the backend http server
        import socket
        s = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
        s.setsockopt(socket.SOL_SOCKET, socket.SO_REUSEADDR, 1)
        s.bind((host, 0))
        port = s.getsockname()[1]
        s.close()
        bind = '%s:%d' % (host, port)

        daemons += [
            ('https', ['https', '-host', https_host, '-listen', host + ':' + https_port, bind]),
        ]

    # A better log-format for local dev when running through honcho,
    # but if there aren't any other daemons, we don't want to override.
    if daemons:
        uwsgi_overrides['log-format'] = '"%(method) %(uri) %(proto)" %(status) %(size)'
    else:
        uwsgi_overrides['log-format'] = '[%(ltime)] "%(method) %(uri) %(proto)" %(status) %(size)'

    server = SentryHTTPServer(host=host, port=port, workers=1, extra_options=uwsgi_overrides)

    # If we don't need any other daemons, just launch a normal uwsgi webserver
    # and avoid dealing with subprocesses
    if not daemons:
        return server.run()

    import sys
    from subprocess import list2cmdline
    from honcho.manager import Manager

    os.environ['PYTHONUNBUFFERED'] = 'true'
    if browser_reload:
        os.environ['WEBPACK_LIVERELOAD'] = '1'

    # Make sure that the environment is prepared before honcho takes over
    # This sets all the appropriate uwsgi env vars, etc
    server.prepare_environment()
    daemons += [
        ('server', ['sentry', 'run', 'web']),
    ]

    cwd = os.path.realpath(os.path.join(settings.PROJECT_ROOT, os.pardir, os.pardir))

    manager = Manager()
    for name, cmd in daemons:
        manager.add_process(
            name, list2cmdline(cmd),
            quiet=False, cwd=cwd,
        )

    manager.loop()
    sys.exit(manager.returncode)
Esempio n. 3
0
def devserver(reload, watchers, workers, browser_reload, environment, bind):
    "Starts a lightweight web server for development."
    if ':' in bind:
        host, port = bind.split(':', 1)
        port = int(port)
    else:
        host = bind
        port = None

    import os

    os.environ['SENTRY_ENVIRONMENT'] = environment

    from django.conf import settings
    from sentry import options
    from sentry.services.http import SentryHTTPServer

    url_prefix = options.get('system.url-prefix', '')
    needs_https = url_prefix.startswith('https://')
    has_https = False

    if needs_https:
        from subprocess import check_output
        try:
            check_output(['which', 'https'])
            has_https = True
        except Exception:
            has_https = False
            from sentry.runner.initializer import show_big_error
            show_big_error([
                'missing `https` on your `$PATH`, but https is needed',
                '`$ brew install mattrobenolt/stuff/https`',
            ])

    uwsgi_overrides = {
        # Make sure we don't try and use uwsgi protocol
        'protocol': 'http',
        # Make sure we reload really quickly for local dev in case it
        # doesn't want to shut down nicely on it's own, NO MERCY
        'worker-reload-mercy': 2,
        # We need stdin to support pdb in devserver
        'honour-stdin': True,
    }

    if reload:
        uwsgi_overrides['py-autoreload'] = 1

    daemons = []

    if watchers:
        daemons += settings.SENTRY_WATCHERS

    if workers:
        if settings.CELERY_ALWAYS_EAGER:
            raise click.ClickException(
                'Disable CELERY_ALWAYS_EAGER in your settings file to spawn workers.'
            )

        daemons += [
            ('worker', ['sentry', 'run', 'worker', '-c', '1', '--autoreload']),
            ('cron', ['sentry', 'run', 'cron', '--autoreload']),
        ]

    if needs_https and has_https:
        from six.moves.urllib.parse import urlparse
        parsed_url = urlparse(url_prefix)
        https_port = six.text_type(parsed_url.port or 443)
        https_host = parsed_url.hostname

        # Determine a random port for the backend http server
        import socket
        s = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
        s.setsockopt(socket.SOL_SOCKET, socket.SO_REUSEADDR, 1)
        s.bind((host, 0))
        port = s.getsockname()[1]
        s.close()
        bind = '%s:%d' % (host, port)

        daemons += [
            ('https', [
                'https', '-host', https_host, '-listen',
                host + ':' + https_port, bind
            ]),
        ]

    # A better log-format for local dev when running through honcho,
    # but if there aren't any other daemons, we don't want to override.
    if daemons:
        uwsgi_overrides[
            'log-format'] = '"%(method) %(uri) %(proto)" %(status) %(size)'
    else:
        uwsgi_overrides[
            'log-format'] = '[%(ltime)] "%(method) %(uri) %(proto)" %(status) %(size)'

    server = SentryHTTPServer(host=host,
                              port=port,
                              workers=1,
                              extra_options=uwsgi_overrides)

    # If we don't need any other daemons, just launch a normal uwsgi webserver
    # and avoid dealing with subprocesses
    if not daemons:
        return server.run()

    import sys
    from subprocess import list2cmdline
    from honcho.manager import Manager

    os.environ['PYTHONUNBUFFERED'] = 'true'
    if browser_reload:
        os.environ['WEBPACK_LIVERELOAD'] = '1'

    # Make sure that the environment is prepared before honcho takes over
    # This sets all the appropriate uwsgi env vars, etc
    server.prepare_environment()
    daemons += [
        ('server', ['sentry', 'run', 'web']),
    ]

    cwd = os.path.realpath(
        os.path.join(settings.PROJECT_ROOT, os.pardir, os.pardir))

    manager = Manager()
    for name, cmd in daemons:
        manager.add_process(
            name,
            list2cmdline(cmd),
            quiet=False,
            cwd=cwd,
        )

    manager.loop()
    sys.exit(manager.returncode)
Esempio n. 4
0
def devserver(reload, watchers, workers, bind):
    "Starts a lightweight web server for development."
    if ':' in bind:
        host, port = bind.split(':', 1)
        port = int(port)
    else:
        host = bind
        port = None

    import os
    from django.conf import settings
    from sentry.services.http import SentryHTTPServer

    uwsgi_overrides = {
        # Make sure we don't try and use uwsgi protocol
        'protocol': 'http',
        # Make sure we reload really quickly for local dev in case it
        # doesn't want to shut down nicely on it's own, NO MERCY
        'worker-reload-mercy': 2,
    }

    if reload:
        uwsgi_overrides['py-autoreload'] = 1

    daemons = []

    if watchers:
        daemons += settings.SENTRY_WATCHERS

    if workers:
        if settings.CELERY_ALWAYS_EAGER:
            raise click.ClickException(
                'Disable CELERY_ALWAYS_EAGER in your settings file to spawn workers.'
            )

        daemons += [
            ('worker', ['sentry', 'celery', 'worker', '-c', '1', '-l',
                        'INFO']),
            ('beat', ['sentry', 'celery', 'beat', '-l', 'INFO']),
        ]

    # A better log-format for local dev when running through honcho,
    # but if there aren't any other daemons, we don't want to override.
    if daemons:
        uwsgi_overrides[
            'log-format'] = '"%(method) %(uri) %(proto)" %(status) %(size)'
    else:
        uwsgi_overrides[
            'log-format'] = '[%(ltime)] "%(method) %(uri) %(proto)" %(status) %(size)'

    server = SentryHTTPServer(host=host,
                              port=port,
                              workers=1,
                              extra_options=uwsgi_overrides)

    # If we don't need any other daemons, just launch a normal uwsgi webserver
    # and avoid dealing with subprocesses
    if not daemons:
        return server.run()

    import sys
    from subprocess import list2cmdline
    from honcho.manager import Manager

    os.environ['PYTHONUNBUFFERED'] = 'true'

    # Make sure that the environment is prepared before honcho takes over
    # This sets all the appropriate uwsgi env vars, etc
    server.prepare_environment()
    daemons += [
        ('server', ['sentry', 'run', 'web']),
    ]

    cwd = os.path.realpath(
        os.path.join(settings.PROJECT_ROOT, os.pardir, os.pardir))

    manager = Manager()
    for name, cmd in daemons:
        manager.add_process(
            name,
            list2cmdline(cmd),
            quiet=False,
            cwd=cwd,
        )

    manager.loop()
    sys.exit(manager.returncode)
Esempio n. 5
0
def devserver(reload, watchers, workers, experimental_spa, styleguide, prefix, environment, bind):
    "Starts a lightweight web server for development."
    if ":" in bind:
        host, port = bind.split(":", 1)
        port = int(port)
    else:
        host = bind
        port = None

    import os

    os.environ["SENTRY_ENVIRONMENT"] = environment

    from django.conf import settings
    from sentry import options
    from sentry.services.http import SentryHTTPServer

    url_prefix = options.get("system.url-prefix", "")
    parsed_url = urlparse(url_prefix)
    # Make sure we're trying to use a port that we can actually bind to
    needs_https = parsed_url.scheme == "https" and (parsed_url.port or 443) > 1024
    has_https = False

    if needs_https:
        from subprocess import check_output

        try:
            check_output(["which", "https"])
            has_https = True
        except Exception:
            has_https = False
            from sentry.runner.initializer import show_big_error

            show_big_error(
                [
                    "missing `https` on your `$PATH`, but https is needed",
                    "`$ brew install mattrobenolt/stuff/https`",
                ]
            )

    uwsgi_overrides = {
        # Make sure we don't try and use uwsgi protocol
        "protocol": "http",
        # Make sure we reload really quickly for local dev in case it
        # doesn't want to shut down nicely on it's own, NO MERCY
        "worker-reload-mercy": 2,
        # We need stdin to support pdb in devserver
        "honour-stdin": True,
        # accept ridiculously large files
        "limit-post": 1 << 30,
        # do something with chunked
        "http-chunked-input": True,
        "thunder-lock": False,
        "timeout": 600,
        "harakiri": 600,
    }

    if reload:
        uwsgi_overrides["py-autoreload"] = 1

    daemons = []

    if experimental_spa:
        os.environ["SENTRY_EXPERIMENTAL_SPA"] = "1"
        if not watchers:
            click.secho(
                "Using experimental SPA mode without watchers enabled has no effect",
                err=True,
                fg="yellow",
            )

    # We proxy all requests through webpacks devserver on the configured port.
    # The backend is served on port+1 and is proxied via the webpack
    # configuration.
    if watchers:
        daemons += settings.SENTRY_WATCHERS

        proxy_port = port
        port = port + 1

        os.environ["SENTRY_WEBPACK_PROXY_PORT"] = "%s" % proxy_port
        os.environ["SENTRY_BACKEND_PORT"] = "%s" % port

        # Replace the webpack watcher with the drop-in webpack-dev-server
        webpack_config = next(w for w in daemons if w[0] == "webpack")[1]
        webpack_config[0] = os.path.join(
            *os.path.split(webpack_config[0])[0:-1] + ("webpack-dev-server",)
        )

        daemons = [w for w in daemons if w[0] != "webpack"] + [("webpack", webpack_config)]

    if workers:
        if settings.CELERY_ALWAYS_EAGER:
            raise click.ClickException(
                "Disable CELERY_ALWAYS_EAGER in your settings file to spawn workers."
            )

        daemons += [
            ("worker", ["sentry", "run", "worker", "-c", "1", "--autoreload"]),
            ("cron", ["sentry", "run", "cron", "--autoreload"]),
        ]

        from sentry import eventstream

        if eventstream.requires_post_process_forwarder():
            daemons += [
                (
                    "relay",
                    [
                        "sentry",
                        "run",
                        "post-process-forwarder",
                        "--loglevel=debug",
                        "--commit-batch-size=1",
                    ],
                )
            ]

    if needs_https and has_https:
        https_port = six.text_type(parsed_url.port)
        https_host = parsed_url.hostname

        # Determine a random port for the backend http server
        import socket

        s = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
        s.setsockopt(socket.SOL_SOCKET, socket.SO_REUSEADDR, 1)
        s.bind((host, 0))
        port = s.getsockname()[1]
        s.close()
        bind = "%s:%d" % (host, port)

        daemons += [
            ("https", ["https", "-host", https_host, "-listen", host + ":" + https_port, bind])
        ]

    # A better log-format for local dev when running through honcho,
    # but if there aren't any other daemons, we don't want to override.
    if daemons:
        uwsgi_overrides["log-format"] = '"%(method) %(uri) %(proto)" %(status) %(size)'
    else:
        uwsgi_overrides["log-format"] = '[%(ltime)] "%(method) %(uri) %(proto)" %(status) %(size)'

    server = SentryHTTPServer(host=host, port=port, workers=1, extra_options=uwsgi_overrides)

    # If we don't need any other daemons, just launch a normal uwsgi webserver
    # and avoid dealing with subprocesses
    if not daemons:
        return server.run()

    import sys
    from subprocess import list2cmdline
    from honcho.manager import Manager
    from honcho.printer import Printer

    os.environ["PYTHONUNBUFFERED"] = "true"

    # Make sure that the environment is prepared before honcho takes over
    # This sets all the appropriate uwsgi env vars, etc
    server.prepare_environment()
    daemons += [("server", ["sentry", "run", "web"])]

    if styleguide:
        daemons += [("storybook", ["./bin/yarn", "storybook"])]

    cwd = os.path.realpath(os.path.join(settings.PROJECT_ROOT, os.pardir, os.pardir))

    manager = Manager(Printer(prefix=prefix))
    for name, cmd in daemons:
        manager.add_process(name, list2cmdline(cmd), quiet=False, cwd=cwd)

    manager.loop()
    sys.exit(manager.returncode)
Esempio n. 6
0
def devserver(reload, watchers, workers, browser_reload, styleguide, prefix,
              environment, bind):
    "Starts a lightweight web server for development."
    if ':' in bind:
        host, port = bind.split(':', 1)
        port = int(port)
    else:
        host = bind
        port = None

    import os

    os.environ['SENTRY_ENVIRONMENT'] = environment

    from django.conf import settings
    from sentry import options
    from sentry.services.http import SentryHTTPServer

    url_prefix = options.get('system.url-prefix', '')
    parsed_url = urlparse(url_prefix)
    # Make sure we're trying to use a port that we can actually bind to
    needs_https = (parsed_url.scheme == 'https'
                   and (parsed_url.port or 443) > 1024)
    has_https = False

    if needs_https:
        from subprocess import check_output
        try:
            check_output(['which', 'https'])
            has_https = True
        except Exception:
            has_https = False
            from sentry.runner.initializer import show_big_error
            show_big_error([
                'missing `https` on your `$PATH`, but https is needed',
                '`$ brew install mattrobenolt/stuff/https`',
            ])

    uwsgi_overrides = {
        # Make sure we don't try and use uwsgi protocol
        'protocol': 'http',
        # Make sure we reload really quickly for local dev in case it
        # doesn't want to shut down nicely on it's own, NO MERCY
        'worker-reload-mercy': 2,
        # We need stdin to support pdb in devserver
        'honour-stdin': True,
        # accept ridiculously large files
        'limit-post': 1 << 30,
        # do something with chunked
        'http-chunked-input': True,
        'thunder-lock': False,
        'timeout': 600,
        'harakiri': 600,
    }

    if reload:
        uwsgi_overrides['py-autoreload'] = 1

    daemons = []

    if watchers:
        daemons += settings.SENTRY_WATCHERS

    # When using browser_reload we proxy all requests through webpacks
    # devserver on the configured port. The backend is served on port+1 and is
    # proxied via the webpack configuration.
    if watchers and browser_reload:
        proxy_port = port
        port = port + 1

        os.environ['SENTRY_WEBPACK_PROXY_PORT'] = '%s' % proxy_port
        os.environ['SENTRY_BACKEND_PORT'] = '%s' % port

        # Replace the webpack watcher with the drop-in webpack-dev-server
        webpack_config = next(w for w in daemons if w[0] == 'webpack')[1]
        webpack_config[0] = os.path.join(
            *os.path.split(webpack_config[0])[0:-1] + ('webpack-dev-server', ))

        daemons = [w for w in daemons if w[0] != 'webpack'] + [
            ('webpack', webpack_config),
        ]

    if workers:
        if settings.CELERY_ALWAYS_EAGER:
            raise click.ClickException(
                'Disable CELERY_ALWAYS_EAGER in your settings file to spawn workers.'
            )

        daemons += [
            ('worker', ['sentry', 'run', 'worker', '-c', '1', '--autoreload']),
            ('cron', ['sentry', 'run', 'cron', '--autoreload']),
        ]

        from sentry import eventstream
        if eventstream.requires_post_process_forwarder():
            daemons += [
                ('relay', [
                    'sentry', 'run', 'post-process-forwarder',
                    '--loglevel=debug', '--commit-batch-size=1'
                ]),
            ]

    if needs_https and has_https:
        https_port = six.text_type(parsed_url.port)
        https_host = parsed_url.hostname

        # Determine a random port for the backend http server
        import socket
        s = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
        s.setsockopt(socket.SOL_SOCKET, socket.SO_REUSEADDR, 1)
        s.bind((host, 0))
        port = s.getsockname()[1]
        s.close()
        bind = '%s:%d' % (host, port)

        daemons += [
            ('https', [
                'https', '-host', https_host, '-listen',
                host + ':' + https_port, bind
            ]),
        ]

    # A better log-format for local dev when running through honcho,
    # but if there aren't any other daemons, we don't want to override.
    if daemons:
        uwsgi_overrides[
            'log-format'] = '"%(method) %(uri) %(proto)" %(status) %(size)'
    else:
        uwsgi_overrides[
            'log-format'] = '[%(ltime)] "%(method) %(uri) %(proto)" %(status) %(size)'

    server = SentryHTTPServer(host=host,
                              port=port,
                              workers=1,
                              extra_options=uwsgi_overrides)

    # If we don't need any other daemons, just launch a normal uwsgi webserver
    # and avoid dealing with subprocesses
    if not daemons:
        return server.run()

    import sys
    from subprocess import list2cmdline
    from honcho.manager import Manager
    from honcho.printer import Printer

    os.environ['PYTHONUNBUFFERED'] = 'true'

    # Make sure that the environment is prepared before honcho takes over
    # This sets all the appropriate uwsgi env vars, etc
    server.prepare_environment()
    daemons += [
        ('server', ['sentry', 'run', 'web']),
    ]

    if styleguide:
        daemons += [('storybook', ['yarn', 'storybook'])]

    cwd = os.path.realpath(
        os.path.join(settings.PROJECT_ROOT, os.pardir, os.pardir))

    manager = Manager(Printer(prefix=prefix))
    for name, cmd in daemons:
        manager.add_process(
            name,
            list2cmdline(cmd),
            quiet=False,
            cwd=cwd,
        )

    manager.loop()
    sys.exit(manager.returncode)
Esempio n. 7
0
def devserver(reload, watchers, workers, bind):
    "Starts a lightweight web server for development."
    if ':' in bind:
        host, port = bind.split(':', 1)
        port = int(port)
    else:
        host = bind
        port = None

    import os
    from django.conf import settings
    from sentry.services.http import SentryHTTPServer

    uwsgi_overrides = {
        # Make sure we don't try and use uwsgi protocol
        'protocol': 'http',
        # Make sure we reload really quickly for local dev in case it
        # doesn't want to shut down nicely on it's own, NO MERCY
        'worker-reload-mercy': 2,
    }

    if reload:
        uwsgi_overrides['py-autoreload'] = 1

    daemons = []

    if watchers:
        daemons += settings.SENTRY_WATCHERS

    if workers:
        if settings.CELERY_ALWAYS_EAGER:
            raise click.ClickException('Disable CELERY_ALWAYS_EAGER in your settings file to spawn workers.')

        daemons += [
            ('worker', ['sentry', 'run', 'worker', '-c', '1', '-l', 'INFO', '--autoreload']),
            ('cron', ['sentry', 'run', 'cron', '-l', 'INFO', '--autoreload']),
        ]

    # A better log-format for local dev when running through honcho,
    # but if there aren't any other daemons, we don't want to override.
    if daemons:
        uwsgi_overrides['log-format'] = '"%(method) %(uri) %(proto)" %(status) %(size)'
    else:
        uwsgi_overrides['log-format'] = '[%(ltime)] "%(method) %(uri) %(proto)" %(status) %(size)'

    server = SentryHTTPServer(host=host, port=port, workers=1, extra_options=uwsgi_overrides)

    # If we don't need any other daemons, just launch a normal uwsgi webserver
    # and avoid dealing with subprocesses
    if not daemons:
        return server.run()

    import sys
    from subprocess import list2cmdline
    from honcho.manager import Manager

    os.environ['PYTHONUNBUFFERED'] = 'true'

    # Make sure that the environment is prepared before honcho takes over
    # This sets all the appropriate uwsgi env vars, etc
    server.prepare_environment()
    daemons += [
        ('server', ['sentry', 'run', 'web']),
    ]

    cwd = os.path.realpath(os.path.join(settings.PROJECT_ROOT, os.pardir, os.pardir))

    manager = Manager()
    for name, cmd in daemons:
        manager.add_process(
            name, list2cmdline(cmd),
            quiet=False, cwd=cwd,
        )

    manager.loop()
    sys.exit(manager.returncode)
Esempio n. 8
0
def devserver(reload, watchers, workers, bind):
    "Starts a lightweight web server for development."
    if ':' in bind:
        host, port = bind.split(':', 1)
        port = int(port)
    else:
        host = bind
        port = None

    import os
    from django.conf import settings
    from sentry.services.http import SentryHTTPServer

    uwsgi_overrides = {
        # Make sure we don't try and use uwsgi protocol
        'protocol': 'http',
        # A better log-format for local dev
        'log-format': '"%(method) %(uri) %(proto)" %(status) %(size) "%(referer)" "%(uagent)"'
    }

    if reload:
        uwsgi_overrides['py-autoreload'] = 1

    server = SentryHTTPServer(host=host, port=port, workers=1, extra_options=uwsgi_overrides)

    daemons = []

    if watchers:
        daemons += settings.SENTRY_WATCHERS

    if workers:
        if settings.CELERY_ALWAYS_EAGER:
            raise click.ClickException('Disable CELERY_ALWAYS_EAGER in your settings file to spawn workers.')

        daemons += [
            ('worker', ['sentry', 'celery', 'worker', '-c', '1', '-l', 'INFO']),
            ('beat', ['sentry', 'celery', 'beat', '-l', 'INFO']),
        ]

    # If we don't need any other daemons, just launch a normal uwsgi webserver
    # and avoid dealing with subprocesses
    if not daemons:
        return server.run()

    import sys
    from subprocess import list2cmdline
    from honcho.manager import Manager

    os.environ['PYTHONUNBUFFERED'] = 'true'

    # Make sure that the environment is prepared before honcho takes over
    # This sets all the appropriate uwsgi env vars, etc
    server.prepare_environment()
    daemons += [
        ('server', ['sentry', 'start']),
    ]

    # Change directory globally to affect all subprocesses. This is less than ideal,
    # but Honcho doesn't provide the ability to pass in a cwd to subprocesses yet.
    # See: https://github.com/nickstenning/honcho/pull/170
    cwd = os.path.realpath(os.path.join(settings.PROJECT_ROOT, os.pardir, os.pardir))
    os.chdir(cwd)

    manager = Manager()
    for name, cmd in daemons:
        manager.add_process(
            name, list2cmdline(cmd),
            quiet=False, env=os.environ.copy()
        )

    manager.loop()
    sys.exit(manager.returncode)
Esempio n. 9
0
def devserver(reload, watchers, workers, browser_reload, styleguide, prefix, environment, bind):
    "Starts a lightweight web server for development."
    if ':' in bind:
        host, port = bind.split(':', 1)
        port = int(port)
    else:
        host = bind
        port = None

    import os

    os.environ['SENTRY_ENVIRONMENT'] = environment

    from django.conf import settings
    from sentry import options
    from sentry.services.http import SentryHTTPServer

    url_prefix = options.get('system.url-prefix', '')
    parsed_url = urlparse(url_prefix)
    # Make sure we're trying to use a port that we can actually bind to
    needs_https = (
        parsed_url.scheme == 'https' and
        (parsed_url.port or 443) > 1024
    )
    has_https = False

    if needs_https:
        from subprocess import check_output
        try:
            check_output(['which', 'https'])
            has_https = True
        except Exception:
            has_https = False
            from sentry.runner.initializer import show_big_error
            show_big_error(
                [
                    'missing `https` on your `$PATH`, but https is needed',
                    '`$ brew install mattrobenolt/stuff/https`',
                ]
            )

    uwsgi_overrides = {
        # Make sure we don't try and use uwsgi protocol
        'protocol': 'http',
        # Make sure we reload really quickly for local dev in case it
        # doesn't want to shut down nicely on it's own, NO MERCY
        'worker-reload-mercy': 2,
        # We need stdin to support pdb in devserver
        'honour-stdin': True,
        # accept ridiculously large files
        'limit-post': 1 << 30,
        # do something with chunked
        'http-chunked-input': True,
        'thunder-lock': False,
        'timeout': 600,
        'harakiri': 600,
    }

    if reload:
        uwsgi_overrides['py-autoreload'] = 1

    daemons = []

    if watchers:
        daemons += settings.SENTRY_WATCHERS

    # When using browser_reload we proxy all requests through webpacks
    # devserver on the configured port. The backend is served on port+1 and is
    # proxied via the webpack configuration.
    if watchers and browser_reload:
        proxy_port = port
        port = port + 1

        os.environ['SENTRY_WEBPACK_PROXY_PORT'] = '%s' % proxy_port
        os.environ['SENTRY_BACKEND_PORT'] = '%s' % port

        # Replace the webpack watcher with the drop-in webpack-dev-server
        webpack_config = next(w for w in daemons if w[0] == 'webpack')[1]
        webpack_config[0] = os.path.join(
            *os.path.split(webpack_config[0])[0:-1] + ('webpack-dev-server', )
        )

        daemons = [w for w in daemons if w[0] != 'webpack'] + [
            ('webpack', webpack_config),
        ]

    if workers:
        if settings.CELERY_ALWAYS_EAGER:
            raise click.ClickException(
                'Disable CELERY_ALWAYS_EAGER in your settings file to spawn workers.'
            )

        daemons += [
            ('worker', ['sentry', 'run', 'worker', '-c', '1', '--autoreload']),
            ('cron', ['sentry', 'run', 'cron', '--autoreload']),
        ]

        from sentry import eventstream
        if eventstream.requires_post_process_forwarder():
            daemons += [
                ('relay', ['sentry', 'run', 'post-process-forwarder', '--loglevel=debug', '--commit-batch-size=1']),
            ]

    if needs_https and has_https:
        https_port = six.text_type(parsed_url.port)
        https_host = parsed_url.hostname

        # Determine a random port for the backend http server
        import socket
        s = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
        s.setsockopt(socket.SOL_SOCKET, socket.SO_REUSEADDR, 1)
        s.bind((host, 0))
        port = s.getsockname()[1]
        s.close()
        bind = '%s:%d' % (host, port)

        daemons += [
            ('https', ['https', '-host', https_host, '-listen', host + ':' + https_port, bind]),
        ]

    # A better log-format for local dev when running through honcho,
    # but if there aren't any other daemons, we don't want to override.
    if daemons:
        uwsgi_overrides['log-format'] = '"%(method) %(uri) %(proto)" %(status) %(size)'
    else:
        uwsgi_overrides['log-format'] = '[%(ltime)] "%(method) %(uri) %(proto)" %(status) %(size)'

    server = SentryHTTPServer(host=host, port=port, workers=1, extra_options=uwsgi_overrides)

    # If we don't need any other daemons, just launch a normal uwsgi webserver
    # and avoid dealing with subprocesses
    if not daemons:
        return server.run()

    import sys
    from subprocess import list2cmdline
    from honcho.manager import Manager
    from honcho.printer import Printer

    os.environ['PYTHONUNBUFFERED'] = 'true'

    # Make sure that the environment is prepared before honcho takes over
    # This sets all the appropriate uwsgi env vars, etc
    server.prepare_environment()
    daemons += [
        ('server', ['sentry', 'run', 'web']),
    ]

    if styleguide:
        daemons += [('storybook', ['yarn', 'storybook'])]

    cwd = os.path.realpath(os.path.join(settings.PROJECT_ROOT, os.pardir, os.pardir))

    manager = Manager(Printer(prefix=prefix))
    for name, cmd in daemons:
        manager.add_process(
            name,
            list2cmdline(cmd),
            quiet=False,
            cwd=cwd,
        )

    manager.loop()
    sys.exit(manager.returncode)
Esempio n. 10
0
def devserver(reload, watchers, workers, browser_reload, styleguide, prefix,
              environment, bind, vscode_debug, search_index):
    "Starts a lightweight web server for development."

    if ':' in bind:
        host, port = bind.split(':', 1)
        port = int(port)
    else:
        host = bind
        port = None

    import os

    os.environ['CLIMS_ENVIRONMENT'] = environment

    from sentry.runner import configure
    configure()

    from django.conf import settings
    from sentry import options
    from sentry.services.http import SentryHTTPServer

    # NOTE: We have to set this variable here rather than directly in the config file
    # because the config file is imported before we're able to set the _ENVIRONMENT variable
    settings.DEBUG = environment == 'development'

    url_prefix = options.get('system.url-prefix', '')
    parsed_url = urlparse(url_prefix)
    # Make sure we're trying to use a port that we can actually bind to
    needs_https = (parsed_url.scheme == 'https'
                   and (parsed_url.port or 443) > 1024)
    has_https = False

    if needs_https:
        from subprocess import check_output
        try:
            check_output(['which', 'https'])
            has_https = True
        except Exception:
            has_https = False
            from sentry.runner.initializer import show_big_error
            show_big_error([
                'missing `https` on your `$PATH`, but https is needed',
                '`$ brew install mattrobenolt/stuff/https`',
            ])

    uwsgi_overrides = {
        # Make sure we don't try and use uwsgi protocol
        'protocol': 'http',
        # Make sure we reload really quickly for local dev in case it
        # doesn't want to shut down nicely on it's own, NO MERCY
        'worker-reload-mercy': 2,
        # We need stdin to support pdb in devserver
        'honour-stdin': True,
        # accept ridiculously large files
        'limit-post': 1 << 30,
        # do something with chunked
        'http-chunked-input': True,
    }

    if reload:
        uwsgi_overrides['py-autoreload'] = 1

    daemons = []

    if watchers and not browser_reload:
        daemons += settings.SENTRY_WATCHERS

    # For javascript dev, if browser reload and watchers, then:
    # devserver listen on PORT + 1
    # webpack dev server listen on PORT + 2
    # proxy listen on PORT
    if watchers and browser_reload:
        new_port = port + 1
        os.environ['WEBPACK_DEV_PROXY'] = '%s' % port
        os.environ['WEBPACK_DEV_PORT'] = '%s' % (new_port + 1)
        os.environ['SENTRY_DEVSERVER_PORT'] = '%s' % new_port
        port = new_port

        daemons += [('jsproxy', ['yarn', 'dev-proxy']),
                    ('webpack', ['yarn', 'dev-server'])]

    if workers:
        if settings.CELERY_ALWAYS_EAGER:
            raise click.ClickException(
                'Disable CELERY_ALWAYS_EAGER in your settings file to spawn workers.'
            )

        daemons += [
            ('worker', ['lims', 'run', 'worker', '-c', '1', '--autoreload']),
            ('cron', ['lims', 'run', 'cron', '--autoreload']),
        ]

    if needs_https and has_https:
        https_port = six.text_type(parsed_url.port)
        https_host = parsed_url.hostname

        # Determine a random port for the backend http server
        import socket
        s = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
        s.setsockopt(socket.SOL_SOCKET, socket.SO_REUSEADDR, 1)
        s.bind((host, 0))
        port = s.getsockname()[1]
        s.close()
        bind = '%s:%d' % (host, port)

        daemons += [
            ('https', [
                'https', '-host', https_host, '-listen',
                host + ':' + https_port, bind
            ]),
        ]

    # A better log-format for local dev when running through honcho,
    # but if there aren't any other daemons, we don't want to override.
    if daemons:
        uwsgi_overrides[
            'log-format'] = '"%(method) %(uri) %(proto)" %(status) %(size)'
    else:
        uwsgi_overrides[
            'log-format'] = '[%(ltime)] "%(method) %(uri) %(proto)" %(status) %(size)'

    server = SentryHTTPServer(host=host,
                              port=port,
                              workers=1,
                              extra_options=uwsgi_overrides)

    # If using vscode_debug, currently we're only starting the builtin django server:
    if vscode_debug:
        from django.core.management import execute_from_command_line
        execute_from_command_line(
            ['', 'runserver', '--noreload', '--nothreading'])
        return
    # If we don't need any other daemons, just launch a normal uwsgi webserver
    # and avoid dealing with subprocesses

    if not daemons:
        return server.run()

    import sys
    from subprocess import list2cmdline
    from honcho.manager import Manager
    from honcho.printer import Printer

    os.environ['PYTHONUNBUFFERED'] = 'true'

    # Make sure that the environment is prepared before honcho takes over
    # This sets all the appropriate uwsgi env vars, etc
    server.prepare_environment()
    daemons += [
        ('server', ['lims', 'run', 'web']),
    ]

    if styleguide:
        daemons += [('storybook', ['yarn', 'storybook'])]

    if search_index and False:
        daemons += [('search_index', ['lims', 'run', 'search_index'])]

    cwd = os.path.realpath(
        os.path.join(settings.PROJECT_ROOT, os.pardir, os.pardir))

    manager = Manager(Printer(prefix=prefix))
    for name, cmd in daemons:
        manager.add_process(
            name,
            list2cmdline(cmd),
            quiet=False,
            cwd=cwd,
        )

    manager.loop()
    sys.exit(manager.returncode)