コード例 #1
0
ファイル: command.py プロジェクト: sabrisabah/kobo-install
    def stop_maintenance(cls):
        """
        Stop maintenance mode
        """
        config = Config()
        dict_ = config.get_dict()

        if not config.multi_servers or config.frontend:
            # Shut down maintenance container in case it's up&running
            maintenance_down_command = [
                'docker-compose', '-f', 'docker-compose.maintenance.yml', '-f',
                'docker-compose.maintenance.override.yml', '-p',
                config.get_prefix('maintenance'), 'down'
            ]

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

            # Create and start NGINX container
            frontend_command = [
                'docker-compose', '-f', 'docker-compose.frontend.yml', '-f',
                'docker-compose.frontend.override.yml', '-p',
                config.get_prefix('frontend'), 'up', '-d', 'nginx'
            ]
            CLI.run_command(frontend_command, dict_['kobodocker_path'])

            CLI.colored_print('Maintenance mode has been stopped',
                              CLI.COLOR_SUCCESS)

            dict_['maintenance_enabled'] = False
            config.write_config()
コード例 #2
0
    def __questions_postgres_backups(self):
        """
        Asks all questions about backups.
        """
        self.__dict['use_backup'] = CLI.yes_no_question(
            'Do you want to activate backups?',
            default=self.__dict['use_backup'])
        if self.__dict['use_backup']:
            self.__dict['use_wal_e'] = False

            schedule_regex_pattern = (
                r'^((((\d+(,\d+)*)|(\d+-\d+)|(\*(\/\d+)?)))'
                r'(\s+(((\d+(,\d+)*)|(\d+\-\d+)|(\*(\/\d+)?)))){4})$')
            message = ('Schedules use linux cron syntax with UTC datetimes.\n'
                       'For example, schedule at 12:00 AM E.S.T every Sunday '
                       'would be:\n'
                       '0 5 * * 0\n'
                       '\n'
                       'Please visit https://crontab.guru/ to generate a '
                       'cron schedule.')
            CLI.colored_print('PostgreSQL backup cron expression?',
                              CLI.COLOR_QUESTION)
            self.__dict['postgres_backup_schedule'] = CLI.get_response(
                '~{}'.format(schedule_regex_pattern),
                self.__dict['postgres_backup_schedule'])

            if self.aws:
                self.__questions_aws_backup_settings()
コード例 #3
0
    def __questions_kobo_postgres(self):
        """
        KoBoToolbox's credentials
        """
        # kobo_db_server
        self.__dict['kobo_db_server'] = CLI.colored_input(
            'KoBoToolbox PostgreSQL server?', CLI.COLOR_QUESTION,
            self.__dict['kobo_db_server'])

        # kobo_db_name - Kobo Form
        CLI.colored_print('KoBoToolbox\'s KoboFORM PostgreSQL database name?',
                          CLI.COLOR_QUESTION)
        self.__dict['kobo_db_name'] = CLI.get_response(
            r'~^\w+$', self.__dict['kobo_db_name'], to_lower=False)

        # kobo_cat_db_name - Kobo Form
        CLI.colored_print('KoBoToolbox\'s KoboCAT PostgreSQL database name?',
                          CLI.COLOR_QUESTION)
        self.__dict['kobo_cat_db_name'] = CLI.get_response(
            r'~^\w+$', self.__dict['kobo_cat_db_name'], to_lower=False)

        # kobo_db_port
        self.__dict['kobo_db_port'] = CLI.colored_input(
            'KoBoToolbox PostgreSQL Port?', CLI.COLOR_QUESTION,
            self.__dict['kobo_db_port'])
        # kobo_db_user
        self.__dict['kobo_db_user'] = CLI.colored_input(
            'KoBoToolbox PostgreSQL User?', CLI.COLOR_QUESTION,
            self.__dict['kobo_db_user'])

        # kobo_db_password
        self.__dict['kobo_db_password'] = CLI.colored_input(
            'KoBoToolbox PostgreSQL Password?', CLI.COLOR_QUESTION,
            self.__dict['kobo_db_password'])
コード例 #4
0
def run(force_setup=False):

    if sys.version_info[0] == 2:
        message = (
            'DEPRECATION: Python 2.7 has reached the end of its life on '
            'January 1st, 2020. Please upgrade your Python as Python 2.7 is '
            'not maintained anymore.\n\n'
            'A future version of KoBoInstall will drop support for it.')
        CLI.framed_print(message)

    if not platform.system() in ['Linux', 'Darwin']:
        CLI.colored_print('Not compatible with this OS', CLI.COLOR_ERROR)
    else:
        config = Config()
        dict_ = config.get_dict()
        if config.first_time:
            force_setup = True

        if force_setup:
            dict_ = config.build()
            Setup.clone_kobodocker(config)
            Template.render(config)
            config.init_letsencrypt()
            Setup.update_hosts(dict_)
        else:
            if config.auto_detect_network():
                Template.render(config)
                Setup.update_hosts(dict_)

        Command.start()
コード例 #5
0
ファイル: command.py プロジェクト: jbibar/kobo-install
    def version(cls):
        git_commit_version_command = ['git', 'rev-parse', 'HEAD']
        stdout = CLI.run_command(git_commit_version_command)

        CLI.colored_print('kobo-install Version: {} (build {})'.format(
            Config.KOBO_INSTALL_VERSION,
            stdout.strip()[0:7],
        ), CLI.COLOR_SUCCESS)
コード例 #6
0
ファイル: command.py プロジェクト: kobotoolbox/kobo-install
    def stop(cls, output=True, frontend_only=False):
        """
        Stop containers
        """
        config = Config()
        dict_ = config.get_dict()

        if not config.multi_servers or config.frontend:
            # Shut down maintenance container in case it's up&running
            maintenance_down_command = [
                'docker-compose', '-f', 'docker-compose.maintenance.yml', '-f',
                'docker-compose.maintenance.override.yml', '-p',
                config.get_prefix('maintenance'), 'down'
            ]

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

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

            # Shut down front-end containers
            frontend_command = [
                'docker-compose',
                '-f',
                'docker-compose.frontend.yml',
                '-f',
                'docker-compose.frontend.override.yml',
                '-p',
                config.get_prefix('frontend'),
                'down',
            ]
            cls.__validate_custom_yml(config, frontend_command)
            CLI.run_command(frontend_command, dict_['kobodocker_path'])

        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'), 'down'
            ]

            cls.__validate_custom_yml(config, backend_command)
            CLI.run_command(backend_command, dict_['kobodocker_path'])

        if output:
            CLI.colored_print('KoboToolbox has been stopped',
                              CLI.COLOR_SUCCESS)
コード例 #7
0
ファイル: command.py プロジェクト: sabrisabah/kobo-install
    def start_maintenance(cls):
        config = Config()
        dict_ = config.get_dict()

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

        CLI.run_command(frontend_command, dict_['kobodocker_path'])
        CLI.colored_print('Maintenance mode has been started',
                          CLI.COLOR_SUCCESS)
コード例 #8
0
    def write_unique_id(self):
        try:
            unique_id_file = os.path.join(self.__dict['support_api_path'],
                                          Config.UNIQUE_ID_FILE)
            with open(unique_id_file, 'w') as f:
                f.write(str(self.__dict['unique_id']))

            os.chmod(unique_id_file, stat.S_IWRITE | stat.S_IREAD)
        except (IOError, OSError):
            CLI.colored_print('Could not write unique_id file',
                              CLI.COLOR_ERROR)
            return False

        return True
コード例 #9
0
    def __validate_installation(self):
        """
        Validates if installation is not run over existing data.
        The check is made only the first time the setup is run.
        :return: bool
        """
        if self.first_time:
            postgres_dir_path = os.path.join(self.__dict['support_api_path'],
                                             '.vols', 'db')
            postgres_data_exists = os.path.exists(
                postgres_dir_path) and os.path.isdir(postgres_dir_path)

            if postgres_data_exists:
                # Not a reliable way to detect whether folder contains
                # kobo-install files. We assume that if
                # `docker-compose.backend.template.yml` is there, Docker
                # images are the good ones.
                # TODO Find a better way
                docker_composer_file_path = os.path.join(
                    self.__dict['support_api_path'],
                    'docker-compose.backend.template.yml')
                if not os.path.exists(docker_composer_file_path):
                    message = (
                        'WARNING!\n\n'
                        'You are installing over existing data.\n'
                        '\n'
                        'It is recommended to backup your data and import it '
                        'to a fresh installed (by Support API install) database.\n'
                        '\n'
                        'support-api-install uses these images:\n'
                        '    - PostgreSQL: mdillon/postgis:9.5\n'
                        '\n'
                        'Be sure to upgrade to these versions before going '
                        'further!')
                    CLI.framed_print(message)
                    response = CLI.yes_no_question(
                        'Are you sure you want to continue?', default=False)
                    if response is False:
                        sys.exit(0)
                    else:
                        CLI.colored_print(
                            'Privileges escalation is needed to prepare DB',
                            CLI.COLOR_WARNING)
                        # Write `kobo_first_run` file to run postgres
                        # container's entrypoint flawlessly.
                        os.system(
                            'echo $(date) | sudo tee -a {} > /dev/null'.format(
                                os.path.join(self.__dict['support_api_path'],
                                             '.vols', 'db', 'kobo_first_run')))
コード例 #10
0
    def get_prefix(self, role):
        roles = {
            'frontend': 'support',
            'backend': 'support',
            'dashboards': 'support'
        }

        try:
            prefix_ = roles[role]
        except KeyError:
            CLI.colored_print('Invalid composer file', CLI.COLOR_ERROR)
            sys.exit(1)

        if not self.__dict['docker_prefix']:
            return prefix_

        return '{}-{}'.format(self.__dict['docker_prefix'], prefix_)
コード例 #11
0
    def stop(cls, output=True, frontend_only=False):
        """
        Stop containers
        """
        config_object = Config()
        config = config_object.get_config()

        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), "down"
                ]
                if config.get("docker_prefix", "") != "":
                    backend_command.insert(-1, "-p")
                    backend_command.insert(-1, 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", "down"
            ]
            if config.get("docker_prefix", "") != "":
                frontend_command.insert(-1, "-p")
                frontend_command.insert(-1, config.get("docker_prefix"))
            CLI.run_command(frontend_command, config.get("kobodocker_path"))

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

        if output:
            CLI.colored_print("KoBoToolbox has been stopped",
                              CLI.COLOR_SUCCESS)
コード例 #12
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 frontend containers', CLI.COLOR_INFO)
        else:
            CLI.colored_print('Launching environment', CLI.COLOR_INFO)

            backend_command = [
                'docker-compose',
                '-f',
                'docker-compose.db.yml',
                '-p',
                config.get_prefix('backend'),
                'up',
                '-d'
            ]
            CLI.run_command(backend_command, dict_['support_api_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']

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


            # Start Dashboards container
            frontend_command = ['docker-compose',
                                '-f', 'docker-compose.shiny.yml',
                                '-p', config.get_prefix('dashboards'),
                                'up', '-d']
            CLI.run_command(frontend_command, dict_['support_api_path'])
コード例 #13
0
    def __create_directory(self):
        """
        Create repository directory if it doesn't exist.
        """
        CLI.colored_print('Where do you want to install?', CLI.COLOR_QUESTION)
        while True:
            support_api_path = CLI.colored_input(
                '', CLI.COLOR_QUESTION, self.__dict['support_api_path'])

            if support_api_path.startswith('.'):
                base_dir = os.path.dirname(
                    os.path.dirname(os.path.realpath(__file__)))
                support_api_path = os.path.normpath(
                    os.path.join(base_dir, support_api_path))

            question = 'Please confirm path [{}]'.format(support_api_path)
            response = CLI.yes_no_question(question)
            if response is True:
                if os.path.isdir(support_api_path):
                    break
                else:
                    try:
                        os.makedirs(support_api_path)
                        break
                    except OSError:
                        CLI.colored_print(
                            'Could not create directory {}!'.format(
                                support_api_path), CLI.COLOR_ERROR)
                        CLI.colored_print(
                            'Please make sure you have permissions '
                            'and path is correct', CLI.COLOR_ERROR)

        self.__dict['support_api_path'] = support_api_path
        self.write_unique_id()
        self.__validate_installation()