Ejemplo n.º 1
0
    def info(cls, timeout=600):
        config_object = Config()
        config = config_object.get_config()

        main_url = "{}://{}.{}{}".format(
            "https" if config.get("https") == Config.TRUE else "http",
            config.get("kpi_subdomain"),
            config.get("public_domain_name"),
            ":{}".format(config.get("exposed_nginx_docker_port")) if config.get("exposed_nginx_docker_port")
                                                                     and str(
                config.get("exposed_nginx_docker_port")) != Config.DEFAULT_NGINX_PORT else ""
        )

        stop = False
        start = int(time.time())
        success = False
        hostname = "{}.{}".format(config.get("kpi_subdomain"), config.get("public_domain_name"))
        nginx_port = int(Config.DEFAULT_NGINX_HTTPS_PORT) if config.get("https") == Config.TRUE \
            else int(config.get("exposed_nginx_docker_port", Config.DEFAULT_NGINX_PORT))
        https = config.get("https") == Config.TRUE
        already_retried = False
        while not stop:
            if Network.status_check(hostname, "/service_health/", nginx_port, https) == Network.STATUS_OK_200:
                stop = True
                success = True
            elif int(time.time()) - start >= timeout:
                if timeout > 0:
                    CLI.colored_print(
                        "\n`KoBoToolbox` has not started yet. This is can be normal with low CPU/RAM computers.\n",
                        CLI.COLOR_INFO)
                    CLI.colored_print("Wait for another {} seconds?".format(timeout), CLI.COLOR_SUCCESS)
                    CLI.colored_print("\t1) Yes")
                    CLI.colored_print("\t2) No")
                    response = CLI.get_response([Config.TRUE, Config.FALSE], Config.TRUE)

                    if response == Config.TRUE:
                        start = int(time.time())
                        continue
                    else:
                        if already_retried is False:
                            already_retried = True
                            CLI.colored_print(("\nSometimes frontend containers "
                                               "can not communicate with backend containers.\n"
                                               "Restarting the frontend containers usually fixes it.\n"),
                                              CLI.COLOR_INFO)
                            CLI.colored_print("Do you want to try?".format(timeout), CLI.COLOR_SUCCESS)
                            CLI.colored_print("\t1) Yes")
                            CLI.colored_print("\t2) No")
                            response = CLI.get_response([Config.TRUE, Config.FALSE], Config.TRUE)
                            if response == Config.TRUE:
                                start = int(time.time())
                                cls.restart_frontend()
                                continue
                stop = True
            else:
                sys.stdout.write(".")
                sys.stdout.flush()
                time.sleep(10)

        # Create a new line
        print("")

        if success:
            username = config.get("super_user_username")
            password = config.get("super_user_password")
            username_chars_count = len(username) + 6
            password_chars_count = len(password) + 10
            url_chars_count = len(main_url) + 6
            max_chars_count = max(username_chars_count, password_chars_count, url_chars_count)

            CLI.colored_print("╔═{}═╗".format("═" * max_chars_count), CLI.COLOR_WARNING)
            CLI.colored_print("║ Ready {} ║".format(
                " " * (max_chars_count - len("Ready "))), CLI.COLOR_WARNING)
            CLI.colored_print("║ URL: {}/{} ║".format(
                main_url, " " * (max_chars_count - url_chars_count)), CLI.COLOR_WARNING)
            CLI.colored_print("║ User: {}{} ║".format(
                username, " " * (max_chars_count - username_chars_count)), CLI.COLOR_WARNING)
            CLI.colored_print("║ Password: {}{} ║".format(
                password, " " * (max_chars_count - password_chars_count)), CLI.COLOR_WARNING)
            CLI.colored_print("╚═{}═╝".format("═" * max_chars_count), CLI.COLOR_WARNING)
        else:
            CLI.colored_print("KoBoToolbox could not start! Please try `python3 run.py --logs` to see the logs.", CLI.COLOR_ERROR)

        return success
Ejemplo n.º 2
0
    def start(cls, frontend_only=False):
        config_object = Config()
        config = config_object.get_config()

        cls.stop(output=False, frontend_only=frontend_only)
        if frontend_only:
            CLI.colored_print("Launching frontend containers", CLI.COLOR_SUCCESS)
        else:
            CLI.colored_print("Launching environment", CLI.COLOR_SUCCESS)

        # Test if ports are available
        ports = []
        if config_object.proxy:
            nginx_port = int(config.get("nginx_proxy_port", 80))
        else:
            nginx_port = int(config.get("exposed_nginx_docker_port", 80))

        if frontend_only or config_object.frontend or not config_object.multi_servers:
            ports.append(nginx_port)

        if not frontend_only or config_object.master_backend or config_object.slave_backend:
            ports.append(config.get("postgresql_port", 5432))
            ports.append(config.get("mongo_port", 27017))
            ports.append(config.get("redis_main_port", 6379))
            ports.append(config.get("redis_cache_port", 6380))

        for port in ports:
            if Network.is_port_open(port):
                CLI.colored_print("Port {} is already open. KoboToolbox can't start".format(port),
                                  CLI.COLOR_ERROR)
                sys.exit()

        # Make them up
        if not frontend_only:
            if (config.get("multi") == Config.TRUE and config.get("server_role") == "backend") or \
                    config.get("multi") != Config.TRUE:

                backend_role = config.get("backend_server_role", "master")

                backend_command = ["docker-compose",
                                   "-f", "docker-compose.backend.{}.yml".format(backend_role),
                                   "-f", "docker-compose.backend.{}.override.yml".format(backend_role),
                                   "up", "-d"]
                if config.get("docker_prefix", "") != "":
                    backend_command.insert(-2, "-p")
                    backend_command.insert(-2, config.get("docker_prefix"))

                CLI.run_command(backend_command, config.get("kobodocker_path"))

        if (config.get("multi") == Config.TRUE and config.get("server_role") == "frontend") or \
                config.get("multi") != Config.TRUE:
            frontend_command = ["docker-compose",
                                "-f", "docker-compose.frontend.yml",
                                "-f", "docker-compose.frontend.override.yml",
                                "up", "-d"]

            if config.get("docker_prefix", "") != "":
                frontend_command.insert(-2, "-p")
                frontend_command.insert(-2, config.get("docker_prefix"))

            CLI.run_command(frontend_command, config.get("kobodocker_path"))

            # Start reverse proxy if user uses it.
            if config_object.use_letsencrypt:
                proxy_command = ["docker-compose",
                                 "up", "-d"]
                CLI.run_command(proxy_command, config_object.get_letsencrypt_repo_path())

        if not frontend_only:
            if (config.get("multi") == Config.TRUE and config.get("server_role") == "frontend") or \
                    config.get("multi") != Config.TRUE:
                CLI.colored_print("Waiting for environment to be ready. It can take a few minutes.", CLI.COLOR_SUCCESS)
                cls.info()
            else:
                CLI.colored_print(("Backend server should be up & running! "
                                   "Please look at docker logs for further information"), CLI.COLOR_WARNING)
Ejemplo n.º 3
0
    def start(cls, frontend_only=False):
        config_object = Config()
        config = config_object.get_config()

        cls.stop(output=False, frontend_only=frontend_only)
        if frontend_only:
            CLI.colored_print("Launching frontend containers",
                              CLI.COLOR_SUCCESS)
        else:
            CLI.colored_print("Launching environment", CLI.COLOR_SUCCESS)

        # Test if ports are available
        ports = []
        if config_object.proxy:
            nginx_port = int(config.get("nginx_proxy_port", 80))
        else:
            nginx_port = int(config.get("exposed_nginx_docker_port", 80))

        if frontend_only or config_object.frontend or \
                not config_object.multi_servers:
            ports.append(nginx_port)

        if (not frontend_only or config_object.master_backend or
                config_object.slave_backend) and \
                config_object.expose_backend_ports:
            ports.append(config.get("postgresql_port", 5432))
            ports.append(config.get("mongo_port", 27017))
            ports.append(config.get("redis_main_port", 6379))
            ports.append(config.get("redis_cache_port", 6380))

        for port in ports:
            if Network.is_port_open(port):
                CLI.colored_print(
                    "Port {} is already open. "
                    "KoboToolbox can't start".format(port), CLI.COLOR_ERROR)
                sys.exit(1)

        # Start the back-end containers
        if not frontend_only:
            if not config_object.multi_servers or \
                    config_object.master_backend or config_object.slave_backend:
                backend_role = config.get("backend_server_role", "master")

                backend_command = [
                    "docker-compose", "-f",
                    "docker-compose.backend.{}.yml".format(backend_role), "-f",
                    "docker-compose.backend.{}.override.yml".format(
                        backend_role), "-p",
                    config_object.get_prefix("backend"), "up", "-d"
                ]
                CLI.run_command(backend_command, config.get("kobodocker_path"))

        # If this was previously a shared-database setup, migrate to separate
        # databases for KPI and KoBoCAT
        migrate_single_to_two_databases()

        # Start the front-end containers
        if not config_object.multi_servers or config_object.frontend:
            frontend_command = [
                "docker-compose", "-f", "docker-compose.frontend.yml", "-f",
                "docker-compose.frontend.override.yml", "-p",
                config_object.get_prefix("frontend"), "up", "-d"
            ]

            if config.get('maintenance_enabled', False):
                cls.start_maintenance()
                # Start all front-end services except the non-maintenance NGINX
                frontend_command.extend([
                    s for s in config_object.get_service_names()
                    if s != 'nginx'
                ])

            CLI.run_command(frontend_command, config.get("kobodocker_path"))

            # Start reverse proxy if user uses it.
            if config_object.use_letsencrypt:
                proxy_command = ["docker-compose", "up", "-d"]
                CLI.run_command(proxy_command,
                                config_object.get_letsencrypt_repo_path())

        if config.get('maintenance_enabled', False):
            CLI.colored_print(
                "Maintenance mode is enabled. To resume "
                "normal operation, use `--stop-maintenance`", CLI.COLOR_INFO)
        elif not frontend_only:
            if not config_object.multi_servers or config_object.frontend:
                CLI.colored_print(
                    "Waiting for environment to be ready. "
                    "It can take a few minutes.", CLI.COLOR_SUCCESS)
                cls.info()
            else:
                CLI.colored_print(("Backend server should be up & running! "
                                   "Please look at docker logs for further "
                                   "information"), CLI.COLOR_WARNING)
Ejemplo n.º 4
0
    def info(cls, timeout=600):
        config_object = Config()
        config = config_object.get_config()

        main_url = "{}://{}.{}{}".format(
            "https" if config.get("https") == Config.TRUE else "http",
            config.get("kpi_subdomain"), config.get("public_domain_name"),
            ":{}".format(config.get("exposed_nginx_docker_port"))
            if config.get("exposed_nginx_docker_port")
            and str(config.get("exposed_nginx_docker_port")) != "80" else "")

        stop = False
        start = int(time.time())
        success = False
        hostname = "{}.{}".format(config.get("kpi_subdomain"),
                                  config.get("public_domain_name"))
        nginx_port = 443 if config.get("https") == Config.TRUE else int(
            config.get("exposed_nginx_docker_port", "80"))
        https = config.get("https") == Config.TRUE
        already_retried = None if config_object.first_time else False
        while not stop:
            if Network.status_check(hostname, "/service_health/", nginx_port,
                                    https) == Network.STATUS_OK_200:
                stop = True
                success = True
            elif int(time.time()) - start >= timeout:
                if timeout > 0:
                    # sometimes frontend can not communicate with backend. docker-compose down/up fixes it.
                    if already_retried is False:
                        CLI.colored_print((
                            "\n`KoBoToolbox` has not started yet, sometimes frontend containers "
                            "can not communicate with backend containers.\n"
                            "Let's restart frontend containers.\n"),
                                          CLI.COLOR_INFO)
                        already_retried = True
                        start = int(time.time())
                        cls.restart_frontend()
                        continue
                    else:
                        if config_object.first_time and already_retried is None:
                            CLI.colored_print(
                                "\n`KoBoToolbox` has not started yet, wait for another {} seconds!"
                                .format(timeout), CLI.COLOR_INFO)
                            start = int(time.time())
                            already_retried = False
                            continue
                stop = True
            else:
                sys.stdout.write(".")
                sys.stdout.flush()
                time.sleep(10)

        # Create a new line
        print("")

        if success:
            username = config.get("super_user_username")
            password = config.get("super_user_password")
            username_chars_count = len(username) + 6
            password_chars_count = len(password) + 10
            url_chars_count = len(main_url) + 6
            max_chars_count = max(username_chars_count, password_chars_count,
                                  url_chars_count)

            CLI.colored_print("╔═{}═╗".format("═" * max_chars_count),
                              CLI.COLOR_WARNING)
            CLI.colored_print(
                "║ Ready {} ║".format(" " * (max_chars_count - len("Ready "))),
                CLI.COLOR_WARNING)
            CLI.colored_print(
                "║ URL: {}/{} ║".format(
                    main_url, " " * (max_chars_count - url_chars_count)),
                CLI.COLOR_WARNING)
            CLI.colored_print(
                "║ User: {}{} ║".format(
                    username, " " * (max_chars_count - username_chars_count)),
                CLI.COLOR_WARNING)
            CLI.colored_print(
                "║ Password: {}{} ║".format(
                    password, " " * (max_chars_count - password_chars_count)),
                CLI.COLOR_WARNING)
            CLI.colored_print("╚═{}═╝".format("═" * max_chars_count),
                              CLI.COLOR_WARNING)
        else:
            CLI.colored_print(
                "Something went wrong! Please look at docker logs",
                CLI.COLOR_ERROR)

        return success
Ejemplo n.º 5
0
    def start(cls, frontend_only=False):
        config = Config()
        dict_ = config.get_dict()

        cls.stop(output=False, frontend_only=frontend_only)
        if frontend_only:
            CLI.colored_print('Launching front-end containers', CLI.COLOR_INFO)
        else:
            CLI.colored_print('Launching environment', CLI.COLOR_INFO)

        # Test if ports are available
        ports = []
        if config.proxy:
            nginx_port = int(dict_['nginx_proxy_port'])
        else:
            nginx_port = int(dict_['exposed_nginx_docker_port'])

        if frontend_only or config.frontend or \
                not config.multi_servers:
            ports.append(nginx_port)

        if (not frontend_only or config.primary_backend or
                config.secondary_backend) and \
                config.expose_backend_ports:
            ports.append(dict_['postgresql_port'])
            ports.append(dict_['mongo_port'])
            ports.append(dict_['redis_main_port'])
            ports.append(dict_['redis_cache_port'])

        for port in ports:
            if Network.is_port_open(port):
                CLI.colored_print(
                    'Port {} is already open. '
                    'KoboToolbox cannot start'.format(port), CLI.COLOR_ERROR)
                sys.exit(1)

        # Start the back-end containers
        if not frontend_only and config.backend:

            backend_role = dict_['backend_server_role']

            backend_command = [
                'docker-compose', '-f',
                'docker-compose.backend.{}.yml'.format(backend_role), '-f',
                'docker-compose.backend.{}.override.yml'.format(backend_role),
                '-p',
                config.get_prefix('backend'), 'up', '-d'
            ]
            CLI.run_command(backend_command, dict_['kobodocker_path'])

        # Start the front-end containers
        if config.frontend:

            # If this was previously a shared-database setup, migrate to
            # separate databases for KPI and KoBoCAT
            Upgrading.migrate_single_to_two_databases(config)

            frontend_command = [
                'docker-compose', '-f', 'docker-compose.frontend.yml', '-f',
                'docker-compose.frontend.override.yml', '-p',
                config.get_prefix('frontend'), 'up', '-d'
            ]

            if dict_['maintenance_enabled']:
                cls.start_maintenance()
                # Start all front-end services except the non-maintenance NGINX
                frontend_command.extend(
                    [s for s in config.get_service_names() if s != 'nginx'])

            CLI.run_command(frontend_command, dict_['kobodocker_path'])

            # Start reverse proxy if user uses it.
            if config.use_letsencrypt:
                proxy_command = ['docker-compose', 'up', '-d']
                CLI.run_command(proxy_command,
                                config.get_letsencrypt_repo_path())

        if dict_['maintenance_enabled']:
            CLI.colored_print(
                'Maintenance mode is enabled. To resume '
                'normal operation, use `--stop-maintenance`', CLI.COLOR_INFO)
        elif not frontend_only:
            if not config.multi_servers or config.frontend:
                CLI.colored_print(
                    'Waiting for environment to be ready. '
                    'It can take a few minutes.', CLI.COLOR_INFO)
                cls.info()
            else:
                CLI.colored_print((
                    '{} back-end server is starting up and should be '
                    'up & running soon!\nPlease look at docker logs for '
                    'further information: `python3 run.py -cb logs -f`'.format(
                        dict_['backend_server_role'])), CLI.COLOR_WARNING)
Ejemplo n.º 6
0
    def info(cls, timeout=600):
        config = Config()
        dict_ = config.get_dict()

        nginx_port = dict_['exposed_nginx_docker_port']

        main_url = '{}://{}.{}{}'.format(
            'https' if dict_['https'] else 'http', dict_['kpi_subdomain'],
            dict_['public_domain_name'], ':{}'.format(nginx_port) if
            (nginx_port
             and str(nginx_port) != Config.DEFAULT_NGINX_PORT) else '')

        stop = False
        start = int(time.time())
        success = False
        hostname = '{}.{}'.format(dict_['kpi_subdomain'],
                                  dict_['public_domain_name'])
        https = dict_['https']
        nginx_port = int(Config.DEFAULT_NGINX_HTTPS_PORT) \
            if https else int(dict_['exposed_nginx_docker_port'])
        already_retried = False
        while not stop:
            if Network.status_check(hostname, '/service_health/', nginx_port,
                                    https) == Network.STATUS_OK_200:
                stop = True
                success = True
            elif int(time.time()) - start >= timeout:
                if timeout > 0:
                    CLI.colored_print(
                        '\n`KoBoToolbox` has not started yet. '
                        'This is can be normal with low CPU/RAM computers.\n',
                        CLI.COLOR_INFO)
                    question = 'Wait for another {} seconds?'.format(timeout)
                    response = CLI.yes_no_question(question)
                    if response:
                        start = int(time.time())
                        continue
                    else:
                        if not already_retried:
                            already_retried = True
                            CLI.colored_print(
                                '\nSometimes front-end containers cannot '
                                'communicate with back-end containers.\n'
                                'Restarting the front-end containers usually '
                                'fixes it.\n', CLI.COLOR_INFO)
                            question = 'Would you like to try?'
                            response = CLI.yes_no_question(question)
                            if response:
                                start = int(time.time())
                                cls.restart_frontend()
                                continue
                stop = True
            else:
                sys.stdout.write('.')
                sys.stdout.flush()
                time.sleep(10)

        # Create a new line
        print('')

        if success:
            username = dict_['super_user_username']
            password = dict_['super_user_password']

            message = ('Ready\n'
                       'URL: {url}\n'
                       'User: {username}\n'
                       'Password: {password}').format(url=main_url,
                                                      username=username,
                                                      password=password)
            CLI.framed_print(message, color=CLI.COLOR_SUCCESS)

        else:
            message = ('KoBoToolbox could not start!\n'
                       'Please try `python3 run.py --logs` to see the logs.')
            CLI.framed_print(message, color=CLI.COLOR_ERROR)

        return success